2010-11-02 12:54:50 +01:00
< ? php
2012-04-11 18:49:22 +02:00
/*
2013-01-20 11:23:46 +01:00
* Copyright ( c ) 2010 - 2013 Tinyboard Development Group
2012-04-11 18:49:22 +02:00
*/
2012-04-12 16:18:19 +02:00
if ( realpath ( $_SERVER [ 'SCRIPT_FILENAME' ]) == str_replace ( '\\' , '/' , __FILE__ )) {
2012-04-11 18:49:22 +02:00
// You cannot request this file directly.
exit ;
}
require_once 'inc/display.php' ;
require_once 'inc/template.php' ;
require_once 'inc/database.php' ;
require_once 'inc/events.php' ;
require_once 'inc/lib/gettext/gettext.inc' ;
// the user is not currently logged in as a moderator
$mod = false ;
register_shutdown_function ( 'fatal_error_handler' );
mb_internal_encoding ( 'UTF-8' );
loadConfig ();
function loadConfig () {
global $board , $config , $__ip , $debug , $__version ;
$error = function_exists ( 'error' ) ? 'error' : 'basic_error_function_because_the_other_isnt_loaded_yet' ;
reset_events ();
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_SERVER [ 'REMOTE_ADDR' ]))
2012-04-11 18:49:22 +02:00
$_SERVER [ 'REMOTE_ADDR' ] = '0.0.0.0' ;
2012-05-05 17:33:10 +02:00
$arrays = array (
'db' ,
'cache' ,
'cookies' ,
'error' ,
'dir' ,
'mod' ,
'spam' ,
'flood_filters' ,
'wordfilters' ,
'custom_capcode' ,
'custom_tripcode' ,
'dnsbl' ,
'dnsbl_exceptions' ,
'remote' ,
'allowed_ext' ,
'allowed_ext_files' ,
'file_icons' ,
'footer' ,
'stylesheets' ,
'additional_javascript' ,
'markup' ,
'custom_pages'
);
2012-04-11 18:49:22 +02:00
$config = array ();
2012-04-12 16:18:19 +02:00
foreach ( $arrays as $key ) {
2012-04-11 18:49:22 +02:00
$config [ $key ] = array ();
2011-04-13 14:21:07 +02:00
}
2012-04-11 18:49:22 +02:00
require 'inc/config.php' ;
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( 'inc/instance-config.php' ))
2012-04-11 18:49:22 +02:00
$error ( 'Tinyboard is not configured! Create inc/instance-config.php.' );
2011-10-11 12:49:14 +02:00
2012-04-11 18:49:22 +02:00
require 'inc/instance-config.php' ;
2011-02-16 06:21:14 +01:00
2012-04-12 16:18:19 +02:00
if ( isset ( $board [ 'dir' ]) && file_exists ( $board [ 'dir' ] . '/config.php' )) {
2012-04-11 18:49:22 +02:00
require $board [ 'dir' ] . '/config.php' ;
2011-04-30 10:52:04 +02:00
}
2012-04-12 16:18:19 +02:00
if ( ! isset ( $__version ))
2012-04-11 18:49:22 +02:00
$__version = file_exists ( '.installed' ) ? trim ( file_get_contents ( '.installed' )) : false ;
$config [ 'version' ] = $__version ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'debug' ]) {
if ( ! isset ( $debug )) {
2013-07-16 07:21:06 +02:00
$debug = array ( 'sql' => array (), 'purge' => array (), 'cached' => array (), 'write' => array ());
2012-04-11 18:49:22 +02:00
$debug [ 'start' ] = microtime ( true );
2011-04-22 16:45:32 +02:00
}
}
2012-04-11 18:49:22 +02:00
date_default_timezone_set ( $config [ 'timezone' ]);
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'blotter' ]))
2012-04-11 18:49:22 +02:00
$config [ 'blotter' ] = false ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'post_url' ]))
2012-04-11 18:49:22 +02:00
$config [ 'post_url' ] = $config [ 'root' ] . $config [ 'file_post' ];
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'referer_match' ]))
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
2012-04-11 18:49:22 +02:00
$config [ 'referer_match' ] = '/^' .
( preg_match ( $config [ 'url_regex' ], $config [ 'root' ]) ? '' :
'https?:\/\/' . $_SERVER [ 'HTTP_HOST' ]) .
preg_quote ( $config [ 'root' ], '/' ) .
'(' .
2013-07-31 08:08:55 +02:00
str_replace ( '%s' , $config [ 'board_regex' ], preg_quote ( $config [ 'board_path' ], '/' )) .
2012-04-11 18:49:22 +02:00
'(' .
preg_quote ( $config [ 'file_index' ], '/' ) . '|' .
str_replace ( '%d' , '\d+' , preg_quote ( $config [ 'file_page' ])) .
')?' .
'|' .
2013-07-31 08:08:55 +02:00
str_replace ( '%s' , $config [ 'board_regex' ], preg_quote ( $config [ 'board_path' ], '/' )) .
2012-04-11 18:49:22 +02:00
preg_quote ( $config [ 'dir' ][ 'res' ], '/' ) .
str_replace ( '%d' , '\d+' , preg_quote ( $config [ 'file_page' ], '/' )) .
'|' .
preg_quote ( $config [ 'file_mod' ], '/' ) . '\?\/.+' .
2013-07-31 08:08:55 +02:00
')([#?](.+)?)?$/ui' ;
2011-12-05 17:04:46 +01:00
} else {
2012-04-11 18:49:22 +02:00
// CLI mode
$config [ 'referer_match' ] = '//' ;
}
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'cookies' ][ 'path' ]))
2012-04-11 18:49:22 +02:00
$config [ 'cookies' ][ 'path' ] = & $config [ 'root' ];
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'dir' ][ 'static' ]))
2012-04-11 18:49:22 +02:00
$config [ 'dir' ][ 'static' ] = $config [ 'root' ] . 'static/' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'image_sticky' ]))
2012-04-11 18:49:22 +02:00
$config [ 'image_sticky' ] = $config [ 'dir' ][ 'static' ] . 'sticky.gif' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'image_locked' ]))
2012-04-11 18:49:22 +02:00
$config [ 'image_locked' ] = $config [ 'dir' ][ 'static' ] . 'locked.gif' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'image_bumplocked' ]))
2012-04-11 18:49:22 +02:00
$config [ 'image_bumplocked' ] = $config [ 'dir' ][ 'static' ] . 'sage.gif' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'image_deleted' ]))
2012-04-11 18:49:22 +02:00
$config [ 'image_deleted' ] = $config [ 'dir' ][ 'static' ] . 'deleted.png' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'image_zip' ]))
2012-04-11 18:49:22 +02:00
$config [ 'image_zip' ] = $config [ 'dir' ][ 'static' ] . 'zip.png' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'uri_thumb' ]))
2012-04-11 18:49:22 +02:00
$config [ 'uri_thumb' ] = $config [ 'root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ];
2012-04-12 16:18:19 +02:00
elseif ( isset ( $board [ 'dir' ]))
2012-04-11 18:49:22 +02:00
$config [ 'uri_thumb' ] = sprintf ( $config [ 'uri_thumb' ], $board [ 'dir' ]);
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'uri_img' ]))
2012-04-11 18:49:22 +02:00
$config [ 'uri_img' ] = $config [ 'root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ];
2012-04-12 16:18:19 +02:00
elseif ( isset ( $board [ 'dir' ]))
2012-04-11 18:49:22 +02:00
$config [ 'uri_img' ] = sprintf ( $config [ 'uri_img' ], $board [ 'dir' ]);
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'uri_stylesheets' ]))
2012-04-11 18:49:22 +02:00
$config [ 'uri_stylesheets' ] = $config [ 'root' ] . 'stylesheets/' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'url_stylesheet' ]))
2012-04-11 18:49:22 +02:00
$config [ 'url_stylesheet' ] = $config [ 'uri_stylesheets' ] . 'style.css' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'url_javascript' ]))
2012-04-11 18:49:22 +02:00
$config [ 'url_javascript' ] = $config [ 'root' ] . $config [ 'file_script' ];
2012-04-12 16:18:19 +02:00
if ( ! isset ( $config [ 'additional_javascript_url' ]))
2012-04-11 18:49:22 +02:00
$config [ 'additional_javascript_url' ] = $config [ 'root' ];
2012-04-12 16:18:19 +02:00
if ( $config [ 'root_file' ]) {
2012-04-11 18:49:22 +02:00
chdir ( $config [ 'root_file' ]);
2011-11-18 13:39:13 +01:00
}
2012-04-10 17:18:38 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'verbose_errors' ]) {
2012-04-11 18:49:22 +02:00
error_reporting ( E_ALL );
ini_set ( 'display_errors' , 1 );
2012-04-10 17:18:38 +02:00
}
2012-04-11 18:49:22 +02:00
// Keep the original address to properly comply with other board configurations
2012-04-12 16:18:19 +02:00
if ( ! isset ( $__ip ))
2012-04-11 18:49:22 +02:00
$__ip = $_SERVER [ 'REMOTE_ADDR' ];
2012-04-10 17:18:38 +02:00
2012-04-11 18:49:22 +02:00
// ::ffff:0.0.0.0
2012-04-12 16:18:19 +02:00
if ( preg_match ( '/^\:\:(ffff\:)?(\d+\.\d+\.\d+\.\d+)$/' , $__ip , $m ))
2012-04-11 18:49:22 +02:00
$_SERVER [ 'REMOTE_ADDR' ] = $m [ 2 ];
2012-04-10 17:18:38 +02:00
2012-04-12 16:18:19 +02:00
if ( _setlocale ( LC_ALL , $config [ 'locale' ]) === false ) {
2012-04-11 18:49:22 +02:00
$error ( 'The specified locale (' . $config [ 'locale' ] . ') does not exist on your platform!' );
2011-04-13 15:47:47 +02:00
}
2012-04-10 17:18:38 +02:00
2012-04-12 16:18:19 +02:00
if ( extension_loaded ( 'gettext' )) {
2012-04-11 18:49:22 +02:00
bindtextdomain ( 'tinyboard' , './inc/locale' );
bind_textdomain_codeset ( 'tinyboard' , 'UTF-8' );
textdomain ( 'tinyboard' );
} else {
_bindtextdomain ( 'tinyboard' , './inc/locale' );
_bind_textdomain_codeset ( 'tinyboard' , 'UTF-8' );
_textdomain ( 'tinyboard' );
}
2012-04-10 17:18:38 +02:00
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'syslog' ])
2012-04-11 18:49:22 +02:00
openlog ( 'tinyboard' , LOG_ODELAY , LOG_SYSLOG ); // open a connection to sysem logger
2012-04-12 16:18:19 +02:00
if ( $config [ 'recaptcha' ])
2012-04-11 18:49:22 +02:00
require_once 'inc/lib/recaptcha/recaptchalib.php' ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-11 18:49:22 +02:00
require_once 'inc/cache.php' ;
2012-11-19 00:28:23 +01:00
event ( 'load-config' );
2012-04-11 18:49:22 +02:00
}
function basic_error_function_because_the_other_isnt_loaded_yet ( $message , $priority = true ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'syslog' ] && $priority !== false ) {
2012-04-11 18:49:22 +02:00
// Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant.
_syslog ( $priority !== true ? $priority : LOG_NOTICE , $message );
}
// Yes, this is horrible.
die ( '<!DOCTYPE html><html><head><title>Error</title>' .
'<style type="text/css">' .
'body{text-align:center;font-family:arial, helvetica, sans-serif;font-size:10pt;}' .
'p{padding:0;margin:20px 0;}' .
'p.c{font-size:11px;}' .
'</style></head>' .
'<body><h2>Error</h2>' . $message . '<hr/>' .
'<p class="c">This alternative error page is being displayed because the other couldn\'t be found or hasn\'t loaded yet.</p></body></html>' );
}
function fatal_error_handler () {
2012-04-12 16:18:19 +02:00
if ( $error = error_get_last ()) {
if ( $error [ 'type' ] == E_ERROR ) {
if ( function_exists ( 'error' )) {
2012-04-11 18:49:22 +02:00
error ( 'Caught fatal error: ' . $error [ 'message' ] . ' in <strong>' . $error [ 'file' ] . '</strong> on line ' . $error [ 'line' ], LOG_ERR );
} else {
basic_error_function_because_the_other_isnt_loaded_yet ( 'Caught fatal error: ' . $error [ 'message' ] . ' in ' . $error [ 'file' ] . ' on line ' . $error [ 'line' ], LOG_ERR );
}
2011-04-14 09:03:12 +02:00
}
}
2012-04-11 18:49:22 +02:00
}
2012-04-10 17:18:38 +02:00
2012-04-11 18:49:22 +02:00
function _syslog ( $priority , $message ) {
2012-04-12 16:18:19 +02:00
if ( isset ( $_SERVER [ 'REMOTE_ADDR' ], $_SERVER [ 'REQUEST_METHOD' ], $_SERVER [ 'REQUEST_URI' ])) {
2012-04-11 18:49:22 +02:00
// CGI
syslog ( $priority , $message . ' - client: ' . $_SERVER [ 'REMOTE_ADDR' ] . ', request: "' . $_SERVER [ 'REQUEST_METHOD' ] . ' ' . $_SERVER [ 'REQUEST_URI' ] . '"' );
} else {
syslog ( $priority , $message );
}
}
2012-04-10 17:18:38 +02:00
2012-04-12 13:56:01 +02:00
function create_antibot ( $board , $thread = null ) {
2012-04-17 00:16:36 +02:00
require_once dirname ( __FILE__ ) . '/anti-bot.php' ;
2012-04-12 13:56:01 +02:00
return _create_antibot ( $board , $thread );
}
2012-04-11 18:49:22 +02:00
2013-07-18 18:06:26 +02:00
function rebuildThemes ( $action , $board = false ) {
2012-04-11 18:49:22 +02:00
// List themes
$query = query ( " SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL " ) or error ( db_error ());
2012-08-30 17:35:27 +02:00
2012-04-12 16:18:19 +02:00
while ( $theme = $query -> fetch ()) {
2013-07-18 18:06:26 +02:00
rebuildTheme ( $theme [ 'theme' ], $action , $board );
2012-04-11 18:49:22 +02:00
}
}
function loadThemeConfig ( $_theme ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $config [ 'dir' ][ 'themes' ] . '/' . $_theme . '/info.php' ))
2012-04-11 18:49:22 +02:00
return false ;
// Load theme information into $theme
include $config [ 'dir' ][ 'themes' ] . '/' . $_theme . '/info.php' ;
return $theme ;
}
2013-07-18 18:06:26 +02:00
function rebuildTheme ( $theme , $action , $board = false ) {
2012-04-11 18:49:22 +02:00
global $config , $_theme ;
$_theme = $theme ;
$theme = loadThemeConfig ( $_theme );
2012-04-12 16:18:19 +02:00
if ( file_exists ( $config [ 'dir' ][ 'themes' ] . '/' . $_theme . '/theme.php' )) {
2012-04-11 18:49:22 +02:00
require_once $config [ 'dir' ][ 'themes' ] . '/' . $_theme . '/theme.php' ;
2012-04-10 17:18:38 +02:00
2013-07-18 18:06:26 +02:00
$theme [ 'build_function' ]( $action , themeSettings ( $_theme ), $board );
2012-04-11 18:49:22 +02:00
}
}
function themeSettings ( $theme ) {
$query = prepare ( " SELECT `name`, `value` FROM `theme_settings` WHERE `theme` = :theme AND `name` IS NOT NULL " );
$query -> bindValue ( ':theme' , $theme );
$query -> execute () or error ( db_error ( $query ));
$settings = array ();
2012-04-12 16:18:19 +02:00
while ( $s = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
$settings [ $s [ 'name' ]] = $s [ 'value' ];
}
return $settings ;
}
function sprintf3 ( $str , $vars , $delim = '%' ) {
$replaces = array ();
2012-04-12 16:18:19 +02:00
foreach ( $vars as $k => $v ) {
2012-04-11 18:49:22 +02:00
$replaces [ $delim . $k . $delim ] = $v ;
}
return str_replace ( array_keys ( $replaces ),
array_values ( $replaces ), $str );
}
2013-07-31 09:12:06 +02:00
function mb_substr_replace ( $string , $replacement , $start , $length ) {
return mb_substr ( $string , 0 , $start ) . $replacement . mb_substr ( $string , $start + $length );
}
2012-04-11 18:49:22 +02:00
function setupBoard ( $array ) {
global $board , $config ;
$board = array (
2012-04-12 15:23:47 +02:00
'uri' => $array [ 'uri' ],
2012-04-12 18:11:41 +02:00
'title' => $array [ 'title' ],
'subtitle' => $array [ 'subtitle' ]
2012-04-12 15:23:47 +02:00
);
2012-04-11 18:49:22 +02:00
2012-04-12 18:11:41 +02:00
// older versions
$board [ 'name' ] = & $board [ 'title' ];
2012-04-11 18:49:22 +02:00
$board [ 'dir' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]);
$board [ 'url' ] = sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]);
loadConfig ();
2012-04-10 17:18:38 +02:00
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $board [ 'dir' ]))
2012-04-12 15:23:47 +02:00
@ mkdir ( $board [ 'dir' ], 0777 ) or error ( " Couldn't create " . $board [ 'dir' ] . " . Check permissions. " , true );
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $board [ 'dir' ] . $config [ 'dir' ][ 'img' ]))
2012-04-12 15:23:47 +02:00
@ mkdir ( $board [ 'dir' ] . $config [ 'dir' ][ 'img' ], 0777 )
or error ( " Couldn't create " . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . " . Check permissions. " , true );
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ]))
2012-04-12 15:23:47 +02:00
@ mkdir ( $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ], 0777 )
or error ( " Couldn't create " . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . " . Check permissions. " , true );
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ]))
2012-04-12 15:23:47 +02:00
@ mkdir ( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ], 0777 )
or error ( " Couldn't create " . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . " . Check permissions. " , true );
2012-04-11 18:49:22 +02:00
}
function openBoard ( $uri ) {
2013-03-01 00:12:17 +01:00
$board = getBoardInfo ( $uri );
if ( $board ) {
setupBoard ( $board );
return true ;
}
return false ;
}
function getBoardInfo ( $uri ) {
2012-04-11 18:49:22 +02:00
global $config ;
2012-08-30 17:35:27 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ] && ( $board = cache :: get ( 'board_' . $uri ))) {
2013-03-01 00:12:17 +01:00
return $board ;
2011-04-13 15:47:47 +02:00
}
2012-04-11 18:49:22 +02:00
$query = prepare ( " SELECT * FROM `boards` WHERE `uri` = :uri LIMIT 1 " );
$query -> bindValue ( ':uri' , $uri );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $board = $query -> fetch ()) {
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-11 18:49:22 +02:00
cache :: set ( 'board_' . $uri , $board );
2013-03-01 00:12:17 +01:00
return $board ;
2012-08-30 17:35:27 +02:00
}
return false ;
2012-04-11 18:49:22 +02:00
}
2012-04-10 17:18:38 +02:00
2012-04-11 18:49:22 +02:00
function boardTitle ( $uri ) {
2013-03-01 00:12:17 +01:00
$board = getBoardInfo ( $uri );
if ( $board )
2012-04-11 18:49:22 +02:00
return $board [ 'title' ];
2012-08-30 17:35:27 +02:00
return false ;
2012-04-11 18:49:22 +02:00
}
function purge ( $uri ) {
global $config , $debug ;
2012-04-19 15:07:52 +02:00
2013-07-31 08:19:58 +02:00
// Fix for Unicode
$uri = urlencode ( $uri );
$uri = str_replace ( " %2F " , " / " , $uri );
$uri = str_replace ( " %3A " , " : " , $uri );
2012-04-19 15:09:51 +02:00
if ( preg_match ( $config [ 'referer_match' ], $config [ 'root' ]) && isset ( $_SERVER [ 'REQUEST_URI' ])) {
2012-04-11 18:49:22 +02:00
$uri = ( str_replace ( '\\' , '/' , dirname ( $_SERVER [ 'REQUEST_URI' ])) == '/' ? '/' : str_replace ( '\\' , '/' , dirname ( $_SERVER [ 'REQUEST_URI' ])) . '/' ) . $uri ;
} else {
$uri = $config [ 'root' ] . $uri ;
2011-09-20 21:49:07 +02:00
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'debug' ]) {
2012-04-11 18:49:22 +02:00
$debug [ 'purge' ][] = $uri ;
}
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'purge' ] as & $purge ) {
2012-04-11 18:49:22 +02:00
$host = & $purge [ 0 ];
$port = & $purge [ 1 ];
2012-04-19 15:07:52 +02:00
$http_host = isset ( $purge [ 2 ]) ? $purge [ 2 ] : ( isset ( $_SERVER [ 'HTTP_HOST' ]) ? $_SERVER [ 'HTTP_HOST' ] : 'localhost' );
2012-04-11 18:49:22 +02:00
$request = " PURGE { $uri } HTTP/1.1 \r \n Host: { $http_host } \r \n User-Agent: Tinyboard \r \n Connection: Close \r \n \r \n " ;
2012-04-12 16:18:19 +02:00
if ( $fp = fsockopen ( $host , $port , $errno , $errstr , $config [ 'purge_timeout' ])) {
2012-04-11 18:49:22 +02:00
fwrite ( $fp , $request );
fclose ( $fp );
2011-05-23 07:29:58 +02:00
} else {
2012-04-11 18:49:22 +02:00
// Cannot connect?
error ( 'Could not PURGE for ' . $host );
2011-05-21 17:12:57 +02:00
}
}
2012-04-11 18:49:22 +02:00
}
function file_write ( $path , $data , $simple = false , $skip_purge = false ) {
2013-07-16 07:21:06 +02:00
global $config , $debug ;
2011-05-21 17:12:57 +02:00
2012-04-12 16:18:19 +02:00
if ( preg_match ( '/^remote:\/\/(.+)\:(.+)$/' , $path , $m )) {
if ( isset ( $config [ 'remote' ][ $m [ 1 ]])) {
2012-04-11 18:49:22 +02:00
require_once 'inc/remote.php' ;
2011-06-04 10:55:05 +02:00
2012-04-11 18:49:22 +02:00
$remote = new Remote ( $config [ 'remote' ][ $m [ 1 ]]);
$remote -> write ( $data , $m [ 2 ]);
return ;
} else {
error ( 'Invalid remote server: ' . $m [ 1 ]);
2011-05-21 17:13:44 +02:00
}
2011-05-20 09:19:27 +02:00
}
2012-04-12 16:18:19 +02:00
if ( ! $fp = fopen ( $path , $simple ? 'w' : 'c' ))
2012-04-11 18:49:22 +02:00
error ( 'Unable to open file for writing: ' . $path );
2011-05-23 07:29:58 +02:00
2012-04-11 18:49:22 +02:00
// File locking
2012-04-12 16:18:19 +02:00
if ( ! $simple && ! flock ( $fp , LOCK_EX )) {
2012-04-11 18:49:22 +02:00
error ( 'Unable to lock file: ' . $path );
2012-02-16 13:32:28 +01:00
}
2012-04-11 18:49:22 +02:00
// Truncate file
2012-04-12 16:18:19 +02:00
if ( ! $simple && ! ftruncate ( $fp , 0 ))
2012-04-11 18:49:22 +02:00
error ( 'Unable to truncate file: ' . $path );
2011-10-08 08:46:48 +02:00
2012-04-11 18:49:22 +02:00
// Write data
2013-07-16 07:21:06 +02:00
if (( $bytes = fwrite ( $fp , $data )) === false )
2012-04-11 18:49:22 +02:00
error ( 'Unable to write to file: ' . $path );
2010-12-02 08:15:50 +01:00
2012-04-11 18:49:22 +02:00
// Unlock
2012-04-12 16:18:19 +02:00
if ( ! $simple )
2012-04-11 18:49:22 +02:00
flock ( $fp , LOCK_UN );
// Close
2012-04-12 16:18:19 +02:00
if ( ! fclose ( $fp ))
2012-04-11 18:49:22 +02:00
error ( 'Unable to close file: ' . $path );
2012-04-19 15:07:52 +02:00
if ( ! $skip_purge && isset ( $config [ 'purge' ])) {
2012-04-11 18:49:22 +02:00
// Purge cache
2012-04-12 16:18:19 +02:00
if ( basename ( $path ) == $config [ 'file_index' ]) {
2012-04-11 18:49:22 +02:00
// Index file (/index.html); purge "/" as well
$uri = dirname ( $path );
// root
2012-04-12 16:18:19 +02:00
if ( $uri == '.' )
2012-04-11 18:49:22 +02:00
$uri = '' ;
else
$uri .= '/' ;
purge ( $uri );
2011-03-01 11:26:04 +01:00
}
2012-04-11 18:49:22 +02:00
purge ( $path );
2011-03-01 11:26:04 +01:00
}
2013-07-16 07:21:06 +02:00
if ( $config [ 'debug' ]) {
$debug [ 'write' ][] = $path . ': ' . $bytes . ' bytes' ;
}
2012-04-11 18:49:22 +02:00
event ( 'write' , $path );
}
function file_unlink ( $path ) {
global $config , $debug ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'debug' ]) {
if ( ! isset ( $debug [ 'unlink' ]))
2012-04-11 18:49:22 +02:00
$debug [ 'unlink' ] = array ();
$debug [ 'unlink' ][] = $path ;
}
$ret = @ unlink ( $path );
2012-04-12 16:18:19 +02:00
if ( isset ( $config [ 'purge' ]) && $path [ 0 ] != '/' && isset ( $_SERVER [ 'HTTP_HOST' ])) {
2012-04-11 18:49:22 +02:00
// Purge cache
2012-04-12 16:18:19 +02:00
if ( basename ( $path ) == $config [ 'file_index' ]) {
2012-04-11 18:49:22 +02:00
// Index file (/index.html); purge "/" as well
$uri = dirname ( $path );
// root
2012-04-12 16:18:19 +02:00
if ( $uri == '.' )
2012-04-11 18:49:22 +02:00
$uri = '' ;
else
$uri .= '/' ;
purge ( $uri );
2011-01-01 15:37:52 +01:00
}
2012-04-11 18:49:22 +02:00
purge ( $path );
2011-01-01 15:37:52 +01:00
}
2012-04-11 18:49:22 +02:00
event ( 'unlink' , $path );
return $ret ;
}
function hasPermission ( $action = null , $board = null , $_mod = null ) {
global $config ;
2011-11-23 06:12:19 +01:00
2012-04-12 16:18:19 +02:00
if ( isset ( $_mod ))
2012-04-11 18:49:22 +02:00
$mod = & $_mod ;
else
global $mod ;
2012-04-12 16:18:19 +02:00
if ( ! is_array ( $mod ))
2012-04-11 18:49:22 +02:00
return false ;
2012-04-12 16:18:19 +02:00
if ( isset ( $action ) && $mod [ 'type' ] < $action )
2012-04-11 18:49:22 +02:00
return false ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $board ) || $config [ 'mod' ][ 'skip_per_board' ])
2012-04-11 18:49:22 +02:00
return true ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $mod [ 'boards' ]))
2012-04-11 18:49:22 +02:00
return false ;
2012-04-12 16:18:19 +02:00
if ( ! in_array ( '*' , $mod [ 'boards' ]) && ! in_array ( $board , $mod [ 'boards' ]))
2012-04-11 18:49:22 +02:00
return false ;
return true ;
}
function listBoards () {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ] && ( $boards = cache :: get ( 'all_boards' )))
2012-04-11 18:49:22 +02:00
return $boards ;
$query = query ( " SELECT * FROM `boards` ORDER BY `uri` " ) or error ( db_error ());
$boards = $query -> fetchAll ();
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-11 18:49:22 +02:00
cache :: set ( 'all_boards' , $boards );
return $boards ;
}
function checkFlood ( $post ) {
global $board , $config ;
$query = prepare ( sprintf ( " SELECT * FROM `posts_%s` WHERE (`ip` = :ip AND `time` >= :floodtime) OR (`ip` = :ip AND `body` != '' AND `body` = :body AND `time` >= :floodsameiptime) OR (`body` != '' AND `body` = :body AND `time` >= :floodsametime) LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
2012-11-29 04:08:53 +01:00
$query -> bindValue ( ':body' , $post [ 'body' ]);
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':floodtime' , time () - $config [ 'flood_time' ], PDO :: PARAM_INT );
$query -> bindValue ( ':floodsameiptime' , time () - $config [ 'flood_time_ip' ], PDO :: PARAM_INT );
$query -> bindValue ( ':floodsametime' , time () - $config [ 'flood_time_same' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$flood = ( bool ) $query -> fetch ();
2012-04-12 16:18:19 +02:00
if ( event ( 'check-flood' , $post ))
2012-04-11 18:49:22 +02:00
return true ;
return $flood ;
}
function until ( $timestamp ) {
$difference = $timestamp - time ();
2012-04-12 16:18:19 +02:00
if ( $difference < 60 ) {
2013-07-27 07:50:38 +02:00
return $difference . ' ' . ngettext ( 'second' , 'seconds' , $difference );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 ))) . ' ' . ngettext ( 'minute' , 'minutes' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 ))) . ' ' . ngettext ( 'hour' , 'hours' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 * 7 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 ))) . ' ' . ngettext ( 'day' , 'days' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 * 365 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 * 7 ))) . ' ' . ngettext ( 'week' , 'weeks' , $num );
2012-04-11 18:49:22 +02:00
}
2012-08-30 17:35:27 +02:00
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 * 365 ))) . ' ' . ngettext ( 'year' , 'years' , $num );
2012-04-11 18:49:22 +02:00
}
function ago ( $timestamp ) {
$difference = time () - $timestamp ;
2012-04-12 16:18:19 +02:00
if ( $difference < 60 ) {
2013-07-27 07:50:38 +02:00
return $difference . ' ' . ngettext ( 'second' , 'seconds' , $difference );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 ))) . ' ' . ngettext ( 'minute' , 'minutes' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 ))) . ' ' . ngettext ( 'hour' , 'hours' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 * 7 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 ))) . ' ' . ngettext ( 'day' , 'days' , $num );
2012-04-12 16:18:19 +02:00
} elseif ( $difference < 60 * 60 * 24 * 365 ) {
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 * 7 ))) . ' ' . ngettext ( 'week' , 'weeks' , $num );
2012-04-11 18:49:22 +02:00
}
2012-08-30 17:35:27 +02:00
2013-07-27 07:50:38 +02:00
return ( $num = round ( $difference / ( 60 * 60 * 24 * 365 ))) . ' ' . ngettext ( 'year' , 'years' , $num );
2012-04-11 18:49:22 +02:00
}
function displayBan ( $ban ) {
global $config ;
2013-07-16 12:33:37 +02:00
if ( ! $ban [ 'seen' ]) {
$query = prepare ( " UPDATE `bans` SET `seen` = 1 WHERE `id` = :id " );
$query -> bindValue ( ':id' , $ban [ 'id' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
}
2012-04-11 18:49:22 +02:00
$ban [ 'ip' ] = $_SERVER [ 'REMOTE_ADDR' ];
// Show banned page and exit
die (
Element ( 'page.html' , array (
2013-07-27 07:21:30 +02:00
'title' => _ ( 'Banned!' ),
2012-04-11 18:49:22 +02:00
'config' => $config ,
'body' => Element ( 'banned.html' , array (
2011-04-22 16:24:15 +02:00
'config' => $config ,
2012-04-11 18:49:22 +02:00
'ban' => $ban
)
))
));
}
function checkBan ( $board = 0 ) {
global $config ;
2011-04-22 16:24:15 +02:00
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_SERVER [ 'REMOTE_ADDR' ])) {
2012-04-11 18:49:22 +02:00
// Server misconfiguration
return ;
}
2012-04-12 16:18:19 +02:00
if ( event ( 'check-ban' , $board ))
2012-04-11 18:49:22 +02:00
return true ;
2013-07-16 12:33:37 +02:00
$query = prepare ( " SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1 " );
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
$query -> bindValue ( ':board' , $board );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $query -> rowCount () < 1 && $config [ 'ban_range' ]) {
2013-07-16 12:33:37 +02:00
$query = prepare ( " SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1 " );
2011-04-22 16:24:15 +02:00
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
2011-07-27 05:40:27 +02:00
$query -> bindValue ( ':board' , $board );
2011-04-22 16:24:15 +02:00
$query -> execute () or error ( db_error ( $query ));
2011-01-01 15:37:52 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $query -> rowCount () < 1 && $config [ 'ban_cidr' ] && ! isIPv6 ()) {
2012-04-11 18:49:22 +02:00
// my most insane SQL query yet
2013-07-16 12:33:37 +02:00
$query = prepare ( " SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board)
2012-04-11 18:49:22 +02:00
AND (
`ip` REGEXP '^(\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+\)\/(\[0-9]+)$'
AND
: ip >= INET_ATON ( SUBSTRING_INDEX ( `ip` , '/' , 1 ))
AND
: ip < INET_ATON ( SUBSTRING_INDEX ( `ip` , '/' , 1 )) + POW ( 2 , 32 - SUBSTRING_INDEX ( `ip` , '/' , - 1 ))
)
ORDER BY `expires` IS NULL DESC , `expires` DESC LIMIT 1 " );
$query -> bindValue ( ':ip' , ip2long ( $_SERVER [ 'REMOTE_ADDR' ]));
$query -> bindValue ( ':board' , $board );
$query -> execute () or error ( db_error ( $query ));
2011-01-02 15:23:34 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $ban = $query -> fetch ()) {
if ( $ban [ 'expires' ] && $ban [ 'expires' ] < time ()) {
2012-04-11 18:49:22 +02:00
// Ban expired
2013-07-16 12:33:37 +02:00
$query = prepare ( " DELETE FROM `bans` WHERE `id` = :id " );
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':id' , $ban [ 'id' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2013-07-16 12:33:37 +02:00
if ( $config [ 'require_ban_view' ] && ! $ban [ 'seen' ]) {
displayBan ( $ban );
}
2012-04-11 18:49:22 +02:00
return ;
2011-10-10 13:37:39 +02:00
}
2012-04-11 18:49:22 +02:00
displayBan ( $ban );
2011-10-10 13:37:39 +02:00
}
2013-07-16 14:50:39 +02:00
// I'm not sure where else to put this. It doesn't really matter where; it just needs to be called every now and then to keep the ban list tidy.
purge_bans ();
}
// No reason to keep expired bans in the database (except those that haven't been viewed yet)
function purge_bans () {
$query = prepare ( " DELETE FROM `bans` WHERE `expires` IS NOT NULL AND `expires` < :time AND `seen` = 1 " );
$query -> bindValue ( ':time' , time ());
$query -> execute () or error ( db_error ( $query ));
2012-04-11 18:49:22 +02:00
}
function threadLocked ( $id ) {
global $board ;
2011-10-10 13:37:39 +02:00
2012-04-12 16:18:19 +02:00
if ( event ( 'check-locked' , $id ))
2012-04-11 18:49:22 +02:00
return true ;
$query = prepare ( sprintf ( " SELECT `locked` FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ());
2012-04-12 16:18:19 +02:00
if ( ! $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
// Non-existant, so it can't be locked...
return false ;
2010-11-30 13:12:54 +01:00
}
2012-04-11 18:49:22 +02:00
return ( bool ) $post [ 'locked' ];
}
function threadSageLocked ( $id ) {
global $board ;
2012-04-12 16:18:19 +02:00
if ( event ( 'check-sage-locked' , $id ))
2012-04-11 18:49:22 +02:00
return true ;
$query = prepare ( sprintf ( " SELECT `sage` FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ());
2012-04-12 16:18:19 +02:00
if ( ! $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
// Non-existant, so it can't be locked...
return false ;
}
return ( bool ) $post [ 'sage' ];
}
function threadExists ( $id ) {
global $board ;
$query = prepare ( sprintf ( " SELECT 1 FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ());
2012-04-12 16:18:19 +02:00
if ( $query -> rowCount ()) {
2012-04-11 18:49:22 +02:00
return true ;
2012-08-30 17:35:27 +02:00
}
return false ;
2012-04-11 18:49:22 +02:00
}
function post ( array $post ) {
global $pdo , $board ;
2012-10-10 03:57:01 +02:00
$query = prepare ( sprintf ( " INSERT INTO `posts_%s` (`id`, `thread`, `subject`, `email`, `name`, `trip`, `capcode`, `body`, `body_nomarkup`, `time`, `bump`, `thumb`, `thumbwidth`, `thumbheight`, `file`, `filewidth`, `fileheight`, `filesize`, `filename`, `filehash`, `password`, `ip`, `sticky`, `locked`, `sage`, `embed`) VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :thumb, :thumbwidth, :thumbheight, :file, :width, :height, :filesize, :filename, :filehash, :password, :ip, :sticky, :locked, 0, :embed) " , $board [ 'uri' ]));
2012-04-11 18:49:22 +02:00
// Basic stuff
2012-04-12 16:18:19 +02:00
if ( ! empty ( $post [ 'subject' ])) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':subject' , $post [ 'subject' ]);
} else {
$query -> bindValue ( ':subject' , NULL , PDO :: PARAM_NULL );
}
2012-04-12 16:18:19 +02:00
if ( ! empty ( $post [ 'email' ])) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':email' , $post [ 'email' ]);
} else {
$query -> bindValue ( ':email' , NULL , PDO :: PARAM_NULL );
}
2012-04-12 16:18:19 +02:00
if ( ! empty ( $post [ 'trip' ])) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':trip' , $post [ 'trip' ]);
} else {
$query -> bindValue ( ':trip' , NULL , PDO :: PARAM_NULL );
}
$query -> bindValue ( ':name' , $post [ 'name' ]);
$query -> bindValue ( ':body' , $post [ 'body' ]);
$query -> bindValue ( ':body_nomarkup' , $post [ 'body_nomarkup' ]);
$query -> bindValue ( ':time' , isset ( $post [ 'time' ]) ? $post [ 'time' ] : time (), PDO :: PARAM_INT );
$query -> bindValue ( ':password' , $post [ 'password' ]);
$query -> bindValue ( ':ip' , isset ( $post [ 'ip' ]) ? $post [ 'ip' ] : $_SERVER [ 'REMOTE_ADDR' ]);
2013-06-08 12:55:13 +02:00
if ( $post [ 'op' ] && $post [ 'mod' ] && isset ( $post [ 'sticky' ]) && $post [ 'sticky' ]) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':sticky' , 1 , PDO :: PARAM_INT );
} else {
$query -> bindValue ( ':sticky' , 0 , PDO :: PARAM_INT );
}
2013-06-08 12:55:13 +02:00
if ( $post [ 'op' ] && $post [ 'mod' ] && isset ( $post [ 'locked' ]) && $post [ 'locked' ]) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':locked' , 1 , PDO :: PARAM_INT );
} else {
$query -> bindValue ( ':locked' , 0 , PDO :: PARAM_INT );
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'mod' ] && isset ( $post [ 'capcode' ]) && $post [ 'capcode' ]) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':capcode' , $post [ 'capcode' ], PDO :: PARAM_INT );
} else {
$query -> bindValue ( ':capcode' , NULL , PDO :: PARAM_NULL );
}
2012-04-12 16:18:19 +02:00
if ( ! empty ( $post [ 'embed' ])) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':embed' , $post [ 'embed' ]);
} else {
$query -> bindValue ( ':embed' , NULL , PDO :: PARAM_NULL );
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'op' ]) {
2012-04-11 18:49:22 +02:00
// No parent thread, image
$query -> bindValue ( ':thread' , null , PDO :: PARAM_NULL );
} else {
$query -> bindValue ( ':thread' , $post [ 'thread' ], PDO :: PARAM_INT );
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'has_file' ]) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':thumb' , $post [ 'thumb' ]);
$query -> bindValue ( ':thumbwidth' , $post [ 'thumbwidth' ], PDO :: PARAM_INT );
$query -> bindValue ( ':thumbheight' , $post [ 'thumbheight' ], PDO :: PARAM_INT );
$query -> bindValue ( ':file' , $post [ 'file' ]);
2010-12-17 15:18:03 +01:00
2012-04-12 16:18:19 +02:00
if ( isset ( $post [ 'width' ], $post [ 'height' ])) {
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':width' , $post [ 'width' ], PDO :: PARAM_INT );
$query -> bindValue ( ':height' , $post [ 'height' ], PDO :: PARAM_INT );
2010-12-17 15:18:03 +01:00
} else {
$query -> bindValue ( ':width' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':height' , null , PDO :: PARAM_NULL );
}
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':filesize' , $post [ 'filesize' ], PDO :: PARAM_INT );
$query -> bindValue ( ':filename' , $post [ 'filename' ]);
$query -> bindValue ( ':filehash' , $post [ 'filehash' ]);
} else {
$query -> bindValue ( ':thumb' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':thumbwidth' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':thumbheight' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':file' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':width' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':height' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':filesize' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':filename' , null , PDO :: PARAM_NULL );
$query -> bindValue ( ':filehash' , null , PDO :: PARAM_NULL );
2010-12-17 15:18:03 +01:00
}
2012-04-12 16:18:19 +02:00
if ( ! $query -> execute ()) {
2012-04-11 18:49:22 +02:00
undoImage ( $post );
error ( db_error ( $query ));
}
return $pdo -> lastInsertId ();
}
function bumpThread ( $id ) {
global $board ;
2012-04-12 16:18:19 +02:00
if ( event ( 'bump' , $id ))
2012-04-11 18:49:22 +02:00
return true ;
$query = prepare ( sprintf ( " UPDATE `posts_%s` SET `bump` = :time WHERE `id` = :id AND `thread` IS NULL " , $board [ 'uri' ]));
$query -> bindValue ( ':time' , time (), PDO :: PARAM_INT );
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
}
// Remove file from post
function deleteFile ( $id , $remove_entirely_if_already = true ) {
global $board , $config ;
$query = prepare ( sprintf ( " SELECT `thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-05-28 09:08:09 +02:00
if ( ! $post = $query -> fetch ())
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'invalidpost' ]);
2012-04-12 16:18:19 +02:00
if ( $post [ 'file' ] == 'deleted' && ! $post [ 'thread' ])
2012-04-11 18:49:22 +02:00
return ; // Can't delete OP's image completely.
$query = prepare ( sprintf ( " UPDATE `posts_%s` SET `thumb` = NULL, `thumbwidth` = NULL, `thumbheight` = NULL, `filewidth` = NULL, `fileheight` = NULL, `filesize` = NULL, `filename` = NULL, `filehash` = NULL, `file` = :file WHERE `id` = :id " , $board [ 'uri' ]));
2012-04-12 16:18:19 +02:00
if ( $post [ 'file' ] == 'deleted' && $remove_entirely_if_already ) {
2012-04-11 18:49:22 +02:00
// Already deleted; remove file fully
$query -> bindValue ( ':file' , null , PDO :: PARAM_NULL );
} else {
// Delete thumbnail
file_unlink ( $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ] . $post [ 'thumb' ]);
2011-01-21 03:14:55 +01:00
2012-04-11 18:49:22 +02:00
// Delete file
file_unlink ( $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . $post [ 'file' ]);
2011-01-21 03:14:55 +01:00
2012-04-11 18:49:22 +02:00
// Set file to 'deleted'
$query -> bindValue ( ':file' , 'deleted' , PDO :: PARAM_INT );
}
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $post [ 'thread' ])
2012-04-11 18:49:22 +02:00
buildThread ( $post [ 'thread' ]);
2012-05-28 09:08:09 +02:00
else
buildThread ( $id );
2012-04-11 18:49:22 +02:00
}
// rebuild post (markup)
function rebuildPost ( $id ) {
global $board ;
$query = prepare ( sprintf ( " SELECT `body_nomarkup`, `thread` FROM `posts_%s` WHERE `id` = :id " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-08-30 17:35:27 +02:00
if (( ! $post = $query -> fetch ()) || ! $post [ 'body_nomarkup' ])
2012-04-11 18:49:22 +02:00
return false ;
markup ( $body = & $post [ 'body_nomarkup' ]);
$query = prepare ( sprintf ( " UPDATE `posts_%s` SET `body` = :body WHERE `id` = :id " , $board [ 'uri' ]));
$query -> bindValue ( ':body' , $body );
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
buildThread ( $post [ 'thread' ] ? $post [ 'thread' ] : $id );
return true ;
}
// Delete a post (reply or thread)
function deletePost ( $id , $error_if_doesnt_exist = true , $rebuild_after = true ) {
global $board , $config ;
// Select post and replies (if thread) in one query
$query = prepare ( sprintf ( " SELECT `id`,`thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id OR `thread` = :id " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $query -> rowCount () < 1 ) {
if ( $error_if_doesnt_exist )
2011-02-12 07:25:15 +01:00
error ( $config [ 'error' ][ 'invalidpost' ]);
2012-04-11 18:49:22 +02:00
else return false ;
}
$ids = array ();
// Delete posts and maybe replies
2012-04-12 16:18:19 +02:00
while ( $post = $query -> fetch ()) {
if ( ! $post [ 'thread' ]) {
2012-04-11 18:49:22 +02:00
// Delete thread HTML page
file_unlink ( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . sprintf ( $config [ 'file_page' ], $post [ 'id' ]));
2012-04-18 17:19:10 +02:00
$antispam_query = prepare ( 'DELETE FROM `antispam` WHERE `board` = :board AND `thread` = :thread' );
$antispam_query -> bindValue ( ':board' , $board [ 'uri' ]);
$antispam_query -> bindValue ( ':thread' , $post [ 'id' ]);
$antispam_query -> execute () or error ( db_error ( $antispam_query ));
2012-04-12 16:18:19 +02:00
} elseif ( $query -> rowCount () == 1 ) {
2012-04-11 18:49:22 +02:00
// Rebuild thread
$rebuild = & $post [ 'thread' ];
2011-01-21 03:14:55 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'thumb' ]) {
2011-01-21 03:14:55 +01:00
// Delete thumbnail
2011-05-23 07:29:58 +02:00
file_unlink ( $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ] . $post [ 'thumb' ]);
2012-04-11 18:49:22 +02:00
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'file' ]) {
2011-01-21 03:14:55 +01:00
// Delete file
2011-05-23 07:29:58 +02:00
file_unlink ( $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . $post [ 'file' ]);
2011-01-21 03:14:55 +01:00
}
2012-04-11 18:49:22 +02:00
$ids [] = ( int ) $post [ 'id' ];
2011-01-21 03:14:55 +01:00
}
2012-04-11 18:49:22 +02:00
$query = prepare ( sprintf ( " DELETE FROM `posts_%s` WHERE `id` = :id OR `thread` = :id " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2011-12-05 03:17:34 +01:00
2012-04-11 18:49:22 +02:00
$query = prepare ( " SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board AND (`target` = " . implode ( ' OR `target` = ' , $ids ) . " ) " );
$query -> bindValue ( ':board' , $board [ 'uri' ]);
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
while ( $cite = $query -> fetch ()) {
if ( $board [ 'uri' ] != $cite [ 'board' ]) {
if ( ! isset ( $tmp_board ))
2012-04-11 18:49:22 +02:00
$tmp_board = $board [ 'uri' ];
openBoard ( $cite [ 'board' ]);
2011-01-18 14:41:43 +01:00
}
2012-04-11 18:49:22 +02:00
rebuildPost ( $cite [ 'post' ]);
}
2012-04-12 16:18:19 +02:00
if ( isset ( $tmp_board ))
2012-04-11 18:49:22 +02:00
openBoard ( $tmp_board );
$query = prepare ( " DELETE FROM `cites` WHERE (`target_board` = :board AND `target` = :id) OR (`board` = :board AND `post` = :id) " );
$query -> bindValue ( ':board' , $board [ 'uri' ]);
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( isset ( $rebuild ) && $rebuild_after ) {
2012-04-11 18:49:22 +02:00
buildThread ( $rebuild );
}
return true ;
}
function clean () {
global $board , $config ;
$offset = round ( $config [ 'max_pages' ] * $config [ 'threads_per_page' ]);
// I too wish there was an easier way of doing this...
$query = prepare ( sprintf ( " SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset, 9001 " , $board [ 'uri' ]));
$query -> bindValue ( ':offset' , $offset , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
while ( $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
deletePost ( $post [ 'id' ]);
}
}
function index ( $page , $mod = false ) {
global $board , $config , $debug ;
$body = '' ;
$offset = round ( $page * $config [ 'threads_per_page' ] - $config [ 'threads_per_page' ]);
$query = prepare ( sprintf ( " SELECT * FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset,:threads_per_page " , $board [ 'uri' ]));
$query -> bindValue ( ':offset' , $offset , PDO :: PARAM_INT );
$query -> bindValue ( ':threads_per_page' , $config [ 'threads_per_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $query -> rowcount () < 1 && $page > 1 )
2012-04-11 18:49:22 +02:00
return false ;
2012-04-12 16:18:19 +02:00
while ( $th = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
$thread = new Thread (
$th [ 'id' ], $th [ 'subject' ], $th [ 'email' ], $th [ 'name' ], $th [ 'trip' ], $th [ 'capcode' ], $th [ 'body' ], $th [ 'time' ], $th [ 'thumb' ],
$th [ 'thumbwidth' ], $th [ 'thumbheight' ], $th [ 'file' ], $th [ 'filewidth' ], $th [ 'fileheight' ], $th [ 'filesize' ], $th [ 'filename' ], $th [ 'ip' ],
$th [ 'sticky' ], $th [ 'locked' ], $th [ 'sage' ], $th [ 'embed' ], $mod ? '?/' : $config [ 'root' ], $mod
);
2011-12-05 03:17:34 +01:00
2013-01-28 04:27:47 +01:00
if ( $config [ 'cache' ][ 'enabled' ] && $cached = cache :: get ( " thread_index_ { $board [ 'uri' ] } _ { $th [ 'id' ] } " )) {
$replies = $cached [ 'replies' ];
$omitted = $cached [ 'omitted' ];
} else {
2012-09-27 20:46:20 +02:00
$posts = prepare ( sprintf ( " SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit " , $board [ 'uri' ]));
$posts -> bindValue ( ':id' , $th [ 'id' ]);
$posts -> bindValue ( ':limit' , ( $th [ 'sticky' ] ? $config [ 'threads_preview_sticky' ] : $config [ 'threads_preview' ]), PDO :: PARAM_INT );
$posts -> execute () or error ( db_error ( $posts ));
2013-01-28 04:27:47 +01:00
$replies = array_reverse ( $posts -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( count ( $replies ) == ( $th [ 'sticky' ] ? $config [ 'threads_preview_sticky' ] : $config [ 'threads_preview' ])) {
2013-06-18 19:21:41 +02:00
$count = numPosts ( $th [ 'id' ]);
$omitted = array ( 'post_count' => $count [ 'replies' ], 'image_count' => $count [ 'images' ]);
2013-01-28 04:27:47 +01:00
} else {
$omitted = false ;
}
2012-09-27 20:50:25 +02:00
2013-01-23 02:43:46 +01:00
if ( $config [ 'cache' ][ 'enabled' ])
2013-01-28 04:27:47 +01:00
cache :: set ( " thread_index_ { $board [ 'uri' ] } _ { $th [ 'id' ] } " , array (
'replies' => $replies ,
'omitted' => $omitted ,
));
2013-01-23 02:43:46 +01:00
}
2013-01-23 03:42:14 +01:00
2013-01-23 02:43:46 +01:00
$num_images = 0 ;
foreach ( $replies as $po ) {
if ( $po [ 'file' ])
$num_images ++ ;
$thread -> add ( new Post (
$po [ 'id' ], $th [ 'id' ], $po [ 'subject' ], $po [ 'email' ], $po [ 'name' ], $po [ 'trip' ], $po [ 'capcode' ], $po [ 'body' ], $po [ 'time' ],
$po [ 'thumb' ], $po [ 'thumbwidth' ], $po [ 'thumbheight' ], $po [ 'file' ], $po [ 'filewidth' ], $po [ 'fileheight' ], $po [ 'filesize' ],
$po [ 'filename' ], $po [ 'ip' ], $po [ 'embed' ], $mod ? '?/' : $config [ 'root' ], $mod )
);
}
2013-01-28 04:27:47 +01:00
if ( $omitted ) {
$thread -> omitted = $omitted [ 'post_count' ] - ( $th [ 'sticky' ] ? $config [ 'threads_preview_sticky' ] : $config [ 'threads_preview' ]);
$thread -> omitted_images = $omitted [ 'image_count' ] - $num_images ;
2012-04-11 18:49:22 +02:00
}
2011-01-18 14:41:43 +01:00
2012-04-11 18:49:22 +02:00
$body .= $thread -> build ( true );
2011-01-18 14:41:43 +01:00
}
2012-04-11 18:49:22 +02:00
return array (
2012-09-27 20:46:20 +02:00
'board' => $board ,
'body' => $body ,
2012-04-11 18:49:22 +02:00
'post_url' => $config [ 'post_url' ],
'config' => $config ,
'boardlist' => createBoardlist ( $mod )
);
}
2010-11-04 15:39:02 +01:00
2012-04-11 18:49:22 +02:00
function getPageButtons ( $pages , $mod = false ) {
global $config , $board ;
$btn = array ();
$root = ( $mod ? '?/' : $config [ 'root' ]) . $board [ 'dir' ];
2012-04-12 16:18:19 +02:00
foreach ( $pages as $num => $page ) {
if ( isset ( $page [ 'selected' ])) {
2012-04-11 18:49:22 +02:00
// Previous button
2012-04-12 16:18:19 +02:00
if ( $num == 0 ) {
2012-04-11 18:49:22 +02:00
// There is no previous page.
$btn [ 'prev' ] = _ ( 'Previous' );
} else {
$loc = ( $mod ? '?/' . $board [ 'uri' ] . '/' : '' ) .
( $num == 1 ?
$config [ 'file_index' ]
:
sprintf ( $config [ 'file_page' ], $num )
);
2011-05-19 13:42:53 +02:00
2012-04-11 18:49:22 +02:00
$btn [ 'prev' ] = '<form action="' . ( $mod ? '' : $root . $loc ) . '" method="get">' .
( $mod ?
'<input type="hidden" name="status" value="301" />' .
'<input type="hidden" name="r" value="' . htmlentities ( $loc ) . '" />'
: '' ) .
'<input type="submit" value="' . _ ( 'Previous' ) . '" /></form>' ;
2011-02-17 07:07:36 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $num == count ( $pages ) - 1 ) {
2012-04-11 18:49:22 +02:00
// There is no next page.
$btn [ 'next' ] = _ ( 'Next' );
} else {
$loc = ( $mod ? '?/' . $board [ 'uri' ] . '/' : '' ) . sprintf ( $config [ 'file_page' ], $num + 2 );
2011-02-17 07:07:36 +01:00
2012-04-11 18:49:22 +02:00
$btn [ 'next' ] = '<form action="' . ( $mod ? '' : $root . $loc ) . '" method="get">' .
( $mod ?
'<input type="hidden" name="status" value="301" />' .
'<input type="hidden" name="r" value="' . htmlentities ( $loc ) . '" />'
: '' ) .
'<input type="submit" value="' . _ ( 'Next' ) . '" /></form>' ;
2010-11-02 11:57:33 +01:00
}
}
}
2010-12-16 11:28:38 +01:00
2012-04-11 18:49:22 +02:00
return $btn ;
}
function getPages ( $mod = false ) {
global $board , $config ;
2011-02-17 08:37:18 +01:00
2012-04-11 18:49:22 +02:00
// Count threads
$query = query ( sprintf ( " SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` IS NULL " , $board [ 'uri' ])) or error ( db_error ());
2011-01-18 14:41:43 +01:00
2012-04-11 18:49:22 +02:00
$count = current ( $query -> fetch ());
$count = floor (( $config [ 'threads_per_page' ] + $count - 1 ) / $config [ 'threads_per_page' ]);
2012-04-12 16:18:19 +02:00
if ( $count < 1 ) $count = 1 ;
2012-04-11 18:49:22 +02:00
$pages = array ();
2012-04-12 16:18:19 +02:00
for ( $x = 0 ; $x < $count && $x < $config [ 'max_pages' ]; $x ++ ) {
2012-04-11 18:49:22 +02:00
$pages [] = array (
'num' => $x + 1 ,
'link' => $x == 0 ? ( $mod ? '?/' : $config [ 'root' ]) . $board [ 'dir' ] . $config [ 'file_index' ] : ( $mod ? '?/' : $config [ 'root' ]) . $board [ 'dir' ] . sprintf ( $config [ 'file_page' ], $x + 1 )
);
2011-01-18 14:41:43 +01:00
}
2012-04-11 18:49:22 +02:00
return $pages ;
}
function makerobot ( $body ) {
global $config ;
$body = strtolower ( $body );
// Leave only letters
$body = preg_replace ( '/[^a-z]/i' , '' , $body );
// Remove repeating characters
2012-04-12 16:18:19 +02:00
if ( $config [ 'robot_strip_repeating' ])
2012-04-11 18:49:22 +02:00
$body = preg_replace ( '/(.)\\1+/' , '$1' , $body );
return sha1 ( $body );
}
function checkRobot ( $body ) {
2012-08-30 17:35:27 +02:00
if ( empty ( $body ) || event ( 'check-robot' , $body ))
2012-04-11 18:49:22 +02:00
return true ;
$body = makerobot ( $body );
$query = prepare ( " SELECT 1 FROM `robot` WHERE `hash` = :hash LIMIT 1 " );
$query -> bindValue ( ':hash' , $body );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
return true ;
2011-01-20 09:24:23 +01:00
}
2012-08-30 17:35:27 +02:00
// Insert new hash
$query = prepare ( " INSERT INTO `robot` VALUES (:hash) " );
$query -> bindValue ( ':hash' , $body );
$query -> execute () or error ( db_error ( $query ));
return false ;
2012-04-11 18:49:22 +02:00
}
2013-06-18 19:21:41 +02:00
// Returns an associative array with 'replies' and 'images' keys
2012-04-11 18:49:22 +02:00
function numPosts ( $id ) {
global $board ;
2013-06-18 19:21:41 +02:00
$query = prepare ( sprintf ( " SELECT COUNT(*) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread " , $board [ 'uri' ], $board [ 'uri' ]));
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':thread' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2013-06-18 19:21:41 +02:00
$num_posts = $query -> fetch ();
$num_posts = $num_posts [ 'num' ];
$num_images = $query -> fetch ();
$num_images = $num_images [ 'num' ];
return array ( 'replies' => $num_posts , 'images' => $num_images );
2012-04-11 18:49:22 +02:00
}
function muteTime () {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $time = event ( 'mute-time' ))
2012-04-11 18:49:22 +02:00
return $time ;
// Find number of mutes in the past X hours
$query = prepare ( " SELECT COUNT(*) as `count` FROM `mutes` WHERE `time` >= :time AND `ip` = :ip " );
$query -> bindValue ( ':time' , time () - ( $config [ 'robot_mute_hour' ] * 3600 ), PDO :: PARAM_INT );
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
$query -> execute () or error ( db_error ( $query ));
$result = $query -> fetch ();
2012-04-12 16:18:19 +02:00
if ( $result [ 'count' ] == 0 ) return 0 ;
2012-04-11 18:49:22 +02:00
return pow ( $config [ 'robot_mute_multiplier' ], $result [ 'count' ]);
}
function mute () {
// Insert mute
$query = prepare ( " INSERT INTO `mutes` VALUES (:ip, :time) " );
$query -> bindValue ( ':time' , time (), PDO :: PARAM_INT );
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
$query -> execute () or error ( db_error ( $query ));
return muteTime ();
}
function checkMute () {
global $config , $debug ;
2011-01-20 09:24:23 +01:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
2012-04-11 18:49:22 +02:00
// Cached mute?
2012-04-12 16:18:19 +02:00
if (( $mute = cache :: get ( " mute_ ${ _SERVER['REMOTE_ADDR'] } " )) && ( $mutetime = cache :: get ( " mutetime_ ${ _SERVER['REMOTE_ADDR'] } " ))) {
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'youaremuted' ], $mute [ 'time' ] + $mutetime - time ()));
}
2011-01-20 09:24:23 +01:00
}
2012-04-11 18:49:22 +02:00
$mutetime = muteTime ();
2012-04-12 16:18:19 +02:00
if ( $mutetime > 0 ) {
2012-04-11 18:49:22 +02:00
// Find last mute time
$query = prepare ( " SELECT `time` FROM `mutes` WHERE `ip` = :ip ORDER BY `time` DESC LIMIT 1 " );
2011-01-20 09:24:23 +01:00
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ]);
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( ! $mute = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
// What!? He's muted but he's not muted...
return ;
2011-05-19 13:24:17 +02:00
}
2011-02-16 10:37:57 +01:00
2012-04-12 16:18:19 +02:00
if ( $mute [ 'time' ] + $mutetime > time ()) {
if ( $config [ 'cache' ][ 'enabled' ]) {
2012-04-11 18:49:22 +02:00
cache :: set ( " mute_ ${ _SERVER['REMOTE_ADDR'] } " , $mute , $mute [ 'time' ] + $mutetime - time ());
cache :: set ( " mutetime_ ${ _SERVER['REMOTE_ADDR'] } " , $mutetime , $mute [ 'time' ] + $mutetime - time ());
2011-01-20 09:24:23 +01:00
}
2012-04-11 18:49:22 +02:00
// Not expired yet
error ( sprintf ( $config [ 'error' ][ 'youaremuted' ], $mute [ 'time' ] + $mutetime - time ()));
} else {
// Already expired
return ;
2011-01-20 09:24:23 +01:00
}
}
2012-04-11 18:49:22 +02:00
}
function buildIndex () {
global $board , $config ;
$pages = getPages ();
2012-07-04 19:17:51 +02:00
$antibot = create_antibot ( $board [ 'uri' ]);
2012-04-11 18:49:22 +02:00
$page = 1 ;
2012-04-12 16:18:19 +02:00
while ( $page <= $config [ 'max_pages' ] && $content = index ( $page )) {
2013-01-23 18:56:06 +01:00
$filename = $board [ 'dir' ] . ( $page == 1 ? $config [ 'file_index' ] : sprintf ( $config [ 'file_page' ], $page ));
$antibot -> reset ();
2011-02-17 12:03:52 +01:00
2012-04-11 18:49:22 +02:00
$content [ 'pages' ] = $pages ;
$content [ 'pages' ][ $page - 1 ][ 'selected' ] = true ;
$content [ 'btn' ] = getPageButtons ( $content [ 'pages' ]);
2012-07-04 19:17:51 +02:00
$content [ 'antibot' ] = $antibot ;
2013-01-23 18:56:06 +01:00
2012-04-11 18:49:22 +02:00
file_write ( $filename , Element ( 'index.html' , $content ));
2011-02-17 12:03:52 +01:00
2012-04-11 18:49:22 +02:00
$page ++ ;
2011-02-17 12:03:52 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $page < $config [ 'max_pages' ]) {
for (; $page <= $config [ 'max_pages' ]; $page ++ ) {
2011-02-12 07:25:15 +01:00
$filename = $board [ 'dir' ] . ( $page == 1 ? $config [ 'file_index' ] : sprintf ( $config [ 'file_page' ], $page ));
2012-04-11 18:49:22 +02:00
file_unlink ( $filename );
2010-11-02 11:57:33 +01:00
}
}
2012-04-11 18:49:22 +02:00
}
function buildJavascript () {
global $config ;
2011-01-19 02:37:31 +01:00
2012-04-11 18:49:22 +02:00
$stylesheets = array ();
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'stylesheets' ] as $name => $uri ) {
2012-04-11 18:49:22 +02:00
$stylesheets [] = array (
'name' => addslashes ( $name ),
'uri' => addslashes (( ! empty ( $uri ) ? $config [ 'uri_stylesheets' ] : '' ) . $uri ));
}
$script = Element ( 'main.js' , array (
'config' => $config ,
'stylesheets' => $stylesheets
));
2013-07-31 12:54:53 +02:00
// Check if we have translation for the javascripts; if yes, we add it to additional javascripts
list ( $pure_locale ) = explode ( " . " , $config [ 'locale' ]);
if ( file_exists ( $jsloc = " inc/locale/ $pure_locale /LC_MESSAGES/javascript.js " )) {
$script = file_get_contents ( $jsloc ) . " \n \n " . $script ;
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'additional_javascript_compile' ]) {
foreach ( $config [ 'additional_javascript' ] as $file ) {
2012-04-11 18:49:22 +02:00
$script .= file_get_contents ( $file );
2012-03-14 11:44:41 +01:00
}
2011-03-26 16:36:32 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'minify_js' ]) {
2012-04-11 18:49:22 +02:00
require_once 'inc/lib/minify/JSMin.php' ;
$script = JSMin :: minify ( $script );
}
file_write ( $config [ 'file_script' ], $script );
}
function checkDNSBL () {
global $config ;
2012-04-12 16:18:19 +02:00
if ( isIPv6 ())
2012-04-11 18:49:22 +02:00
return ; // No IPv6 support yet.
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_SERVER [ 'REMOTE_ADDR' ]))
2012-04-11 18:49:22 +02:00
return ; // Fix your web server configuration
2012-04-12 16:18:19 +02:00
if ( in_array ( $_SERVER [ 'REMOTE_ADDR' ], $config [ 'dnsbl_exceptions' ]))
2012-04-11 18:49:22 +02:00
return ;
2012-04-15 02:21:43 +02:00
$ipaddr = ReverseIPOctets ( $_SERVER [ 'REMOTE_ADDR' ]);
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'dnsbl' ] as $blacklist ) {
2012-04-15 02:21:43 +02:00
if ( ! is_array ( $blacklist ))
2012-04-11 18:49:22 +02:00
$blacklist = array ( $blacklist );
2011-05-19 09:37:23 +02:00
2012-04-15 02:21:43 +02:00
if (( $lookup = str_replace ( '%' , $ipaddr , $blacklist [ 0 ])) == $blacklist [ 0 ])
$lookup = $ipaddr . '.' . $blacklist [ 0 ];
2011-05-30 09:35:20 +02:00
2012-04-12 16:18:19 +02:00
if ( ! $ip = DNS ( $lookup ))
2012-04-11 18:49:22 +02:00
continue ; // not in list
2011-06-04 17:48:31 +02:00
2012-04-11 18:49:22 +02:00
$blacklist_name = isset ( $blacklist [ 2 ]) ? $blacklist [ 2 ] : $blacklist [ 0 ];
2011-01-19 02:37:31 +01:00
2012-04-12 16:18:19 +02:00
if ( ! isset ( $blacklist [ 1 ])) {
2012-04-11 18:49:22 +02:00
// If you're listed at all, you're blocked.
error ( sprintf ( $config [ 'error' ][ 'dnsbl' ], $blacklist_name ));
2012-04-12 16:18:19 +02:00
} elseif ( is_array ( $blacklist [ 1 ])) {
foreach ( $blacklist [ 1 ] as $octet ) {
if ( $ip == $octet || $ip == '127.0.0.' . $octet )
2012-03-17 20:34:34 +01:00
error ( sprintf ( $config [ 'error' ][ 'dnsbl' ], $blacklist_name ));
2011-05-19 09:37:23 +02:00
}
2012-04-12 16:18:19 +02:00
} elseif ( is_callable ( $blacklist [ 1 ])) {
if ( $blacklist [ 1 ]( $ip ))
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'dnsbl' ], $blacklist_name ));
} else {
2012-04-12 16:18:19 +02:00
if ( $ip == $blacklist [ 1 ] || $ip == '127.0.0.' . $blacklist [ 1 ])
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'dnsbl' ], $blacklist_name ));
2011-05-19 09:37:23 +02:00
}
2011-01-19 02:37:31 +01:00
}
2012-04-11 18:49:22 +02:00
}
function isIPv6 () {
return strstr ( $_SERVER [ 'REMOTE_ADDR' ], ':' ) !== false ;
}
function ReverseIPOctets ( $ip ) {
return implode ( '.' , array_reverse ( explode ( '.' , $ip )));
}
function wordfilters ( & $body ) {
global $config ;
2011-01-19 02:37:31 +01:00
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'wordfilters' ] as $filter ) {
if ( isset ( $filter [ 2 ]) && $filter [ 2 ]) {
2012-04-11 18:49:22 +02:00
$body = preg_replace ( $filter [ 0 ], $filter [ 1 ], $body );
} else {
$body = str_ireplace ( $filter [ 0 ], $filter [ 1 ], $body );
}
2011-02-17 10:32:11 +01:00
}
2012-04-11 18:49:22 +02:00
}
function quote ( $body , $quote = true ) {
global $config ;
2011-02-17 10:32:11 +01:00
2012-04-11 18:49:22 +02:00
$body = str_replace ( '<br/>' , " \n " , $body );
2011-04-06 11:18:36 +02:00
2012-04-11 18:49:22 +02:00
$body = strip_tags ( $body );
$body = preg_replace ( " /(^| \n )/ " , '$1>' , $body );
$body .= " \n " ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'minify_html' ])
2012-04-11 18:49:22 +02:00
$body = str_replace ( " \n " , '
' , $body );
return $body ;
}
function markup_url ( $matches ) {
2013-01-16 19:49:26 +01:00
global $config , $markup_urls ;
2012-04-11 18:49:22 +02:00
$url = $matches [ 1 ];
$after = $matches [ 2 ];
$markup_urls [] = $url ;
2013-07-31 09:43:01 +02:00
return '<a target="_blank" rel="nofollow" href="' . $config [ 'link_prefix' ] . $url . '">' . $url . '</a>' . $after ;
2012-04-11 18:49:22 +02:00
}
function unicodify ( $body ) {
$body = str_replace ( '...' , '…' , $body );
$body = str_replace ( '<--' , '←' , $body );
$body = str_replace ( '-->' , '→' , $body );
// En and em- dashes are rendered exactly the same in
// most monospace fonts (they look the same in code
// editors).
2013-01-23 17:37:15 +01:00
$body = str_replace ( '---' , '—' , $body ); // em dash
2013-02-12 18:25:56 +01:00
$body = str_replace ( '--' , '–' , $body ); // en dash
2012-04-11 18:49:22 +02:00
return $body ;
}
function markup ( & $body , $track_cites = false ) {
global $board , $config , $markup_urls ;
$body = str_replace ( " \r " , '' , $body );
$body = utf8tohtml ( $body );
2013-07-31 04:08:56 +02:00
if ( mysql_version () < 50503 )
$body = mb_encode_numericentity ( $body , array ( 0x010000 , 0xffffff , 0 , 0xffffff ), 'UTF-8' );
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'markup' ] as $markup ) {
if ( is_string ( $markup [ 1 ])) {
2012-04-11 18:49:22 +02:00
$body = preg_replace ( $markup [ 0 ], $markup [ 1 ], $body );
2012-04-12 16:18:19 +02:00
} elseif ( is_callable ( $markup [ 1 ])) {
2012-04-11 18:49:22 +02:00
$body = preg_replace_callback ( $markup [ 0 ], $markup [ 1 ], $body );
2011-04-06 11:18:36 +02:00
}
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'markup_urls' ]) {
2012-04-11 18:49:22 +02:00
$markup_urls = array ();
2012-01-07 01:55:25 +01:00
2012-04-11 18:49:22 +02:00
$body = preg_replace_callback (
'/((?:https?:\/\/|ftp:\/\/|irc:\/\/)[^\s<>()"]+?(?:\([^\s<>()"]*?\)[^\s<>()"]*?)*)((?:\s|<|>|"|\.||\]|!|\?|,|,|")*(?:[\s<>()"]|$))/' ,
'markup_url' ,
$body ,
- 1 ,
$num_links );
2012-01-07 01:54:25 +01:00
2012-04-12 16:18:19 +02:00
if ( $num_links > $config [ 'max_links' ])
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'toomanylinks' ]);
2011-04-12 11:56:37 +02:00
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'auto_unicode' ]) {
2012-04-11 18:49:22 +02:00
$body = unicodify ( $body );
2012-01-05 20:34:21 +01:00
2012-05-08 15:59:54 +02:00
if ( $config [ 'markup_urls' ]) {
foreach ( $markup_urls as & $url ) {
$body = str_replace ( unicodify ( $url ), $url , $body );
}
2012-04-11 18:49:22 +02:00
}
2012-01-30 19:57:25 +01:00
}
2012-04-11 18:49:22 +02:00
// replace tabs with 8 spaces
$body = str_replace ( " \t " , ' ' , $body );
$tracked_cites = array ();
// Cites
2013-07-26 17:01:13 +02:00
if ( isset ( $board ) && preg_match_all ( '/(^|\s)>>(\d+?)([\s,.)?]|$)/m' , $body , $cites , PREG_SET_ORDER | PREG_OFFSET_CAPTURE )) {
2012-04-12 16:18:19 +02:00
if ( count ( $cites [ 0 ]) > $config [ 'max_cites' ]) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'toomanycites' ]);
2010-11-02 11:57:33 +01:00
}
2011-11-16 05:54:35 +01:00
2013-07-26 17:01:13 +02:00
$skip_chars = 0 ;
2013-07-31 09:12:06 +02:00
$body_tmp = $body ;
2013-07-26 17:01:13 +02:00
foreach ( $cites as $matches ) {
$cite = $matches [ 2 ][ 0 ];
2012-04-11 18:49:22 +02:00
$query = prepare ( sprintf ( " SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $cite );
$query -> execute () or error ( db_error ( $query ));
2011-04-22 16:24:15 +02:00
2013-07-31 09:13:51 +02:00
// preg_match_all is not multibyte-safe
2013-07-31 09:12:06 +02:00
foreach ( $matches as & $match ) {
$match [ 1 ] = mb_strlen ( substr ( $body_tmp , 0 , $match [ 1 ]));
}
2012-04-12 16:18:19 +02:00
if ( $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
$replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' .
$config [ 'root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . ( $post [ 'thread' ] ? $post [ 'thread' ] : $post [ 'id' ]) . '.html#' . $cite . '">' .
'>>' . $cite .
'</a>' ;
2010-12-17 15:18:03 +01:00
2013-07-31 09:12:06 +02:00
$body = mb_substr_replace ( $body , $matches [ 1 ][ 0 ] . $replacement . $matches [ 3 ][ 0 ], $matches [ 0 ][ 1 ] + $skip_chars , mb_strlen ( $matches [ 0 ][ 0 ]));
$skip_chars += mb_strlen ( $matches [ 1 ][ 0 ] . $replacement . $matches [ 3 ][ 0 ]) - mb_strlen ( $matches [ 0 ][ 0 ]);
2012-04-12 16:18:19 +02:00
if ( $track_cites && $config [ 'track_cites' ])
2012-04-11 18:49:22 +02:00
$tracked_cites [] = array ( $board [ 'uri' ], $post [ 'id' ]);
2011-04-06 11:18:36 +02:00
}
}
2012-04-11 18:49:22 +02:00
}
2013-07-31 09:12:06 +02:00
2012-04-11 18:49:22 +02:00
// Cross-board linking
2013-07-31 08:08:55 +02:00
if ( preg_match_all ( '/(^|\s)>>>\/(' . $config [ 'board_regex' ] . 'f?)\/(\d+)?([\s,.)?]|$)/um' , $body , $cites , PREG_SET_ORDER | PREG_OFFSET_CAPTURE )) {
2012-04-12 16:18:19 +02:00
if ( count ( $cites [ 0 ]) > $config [ 'max_cites' ]) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'toomanycross' ]);
}
2011-04-06 11:18:36 +02:00
2013-07-26 17:01:13 +02:00
$skip_chars = 0 ;
2013-07-31 09:12:06 +02:00
$body_tmp = $body ;
2013-07-26 17:01:13 +02:00
foreach ( $cites as $matches ) {
$_board = $matches [ 2 ][ 0 ];
$cite = @ $matches [ 3 ][ 0 ];
2011-04-22 16:24:15 +02:00
2013-07-31 09:13:51 +02:00
// preg_match_all is not multibyte-safe
2013-07-31 09:12:06 +02:00
foreach ( $matches as & $match ) {
$match [ 1 ] = mb_strlen ( substr ( $body_tmp , 0 , $match [ 1 ]));
}
2012-04-11 18:49:22 +02:00
// Temporarily store board information because it will be overwritten
$tmp_board = $board [ 'uri' ];
// Check if the board exists, and load settings
2012-04-12 16:18:19 +02:00
if ( openBoard ( $_board )) {
if ( $cite ) {
2012-04-11 18:49:22 +02:00
$query = prepare ( sprintf ( " SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1 " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $cite );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
$replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' .
$config [ 'root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . ( $post [ 'thread' ] ? $post [ 'thread' ] : $post [ 'id' ]) . '.html#' . $cite . '">' .
'>>>/' . $_board . '/' . $cite .
2011-04-06 11:18:36 +02:00
'</a>' ;
2013-07-31 09:12:06 +02:00
$body = mb_substr_replace ( $body , $matches [ 1 ][ 0 ] . $replacement . $matches [ 4 ][ 0 ], $matches [ 0 ][ 1 ] + $skip_chars , mb_strlen ( $matches [ 0 ][ 0 ]));
2013-07-26 17:01:13 +02:00
$skip_chars += mb_strlen ( $matches [ 1 ][ 0 ] . $replacement . $matches [ 4 ][ 0 ]) - mb_strlen ( $matches [ 0 ][ 0 ]);
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $track_cites && $config [ 'track_cites' ])
2012-04-11 18:49:22 +02:00
$tracked_cites [] = array ( $board [ 'uri' ], $post [ 'id' ]);
2011-04-06 11:18:36 +02:00
}
2012-04-11 18:49:22 +02:00
} else {
$replacement = '<a href="' .
$config [ 'root' ] . $board [ 'dir' ] . $config [ 'file_index' ] . '">' .
'>>>/' . $_board . '/' .
'</a>' ;
2013-07-31 09:12:06 +02:00
$body = mb_substr_replace ( $body , $matches [ 1 ][ 0 ] . $replacement . $matches [ 4 ][ 0 ], $matches [ 0 ][ 1 ] + $skip_chars , mb_strlen ( $matches [ 0 ][ 0 ]));
2013-07-26 17:01:13 +02:00
$skip_chars += mb_strlen ( $matches [ 1 ][ 0 ] . $replacement . $matches [ 4 ][ 0 ]) - mb_strlen ( $matches [ 0 ][ 0 ]);
2011-04-06 11:18:36 +02:00
}
2010-11-02 11:57:33 +01:00
}
2012-04-11 18:49:22 +02:00
// Restore main board settings
openBoard ( $tmp_board );
2010-11-02 11:57:33 +01:00
}
}
2012-04-11 18:49:22 +02:00
$body = preg_replace ( " /^ \ s*>.* $ /m " , '<span class="quote">$0</span>' , $body );
2012-04-12 16:18:19 +02:00
if ( $config [ 'strip_superfluous_returns' ])
2012-04-11 18:49:22 +02:00
$body = preg_replace ( '/\s+$/' , '' , $body );
$body = preg_replace ( " / \n / " , '<br/>' , $body );
return $tracked_cites ;
}
2010-11-04 15:39:02 +01:00
2012-04-11 18:49:22 +02:00
function utf8tohtml ( $utf8 ) {
2013-07-31 04:08:56 +02:00
return htmlspecialchars ( $utf8 , ENT_NOQUOTES , 'UTF-8' );
2012-04-11 18:49:22 +02:00
}
2010-11-04 15:39:02 +01:00
2013-07-29 02:33:26 +02:00
function ordutf8 ( $string , & $offset ) {
$code = ord ( substr ( $string , $offset , 1 ));
if ( $code >= 128 ) { // otherwise 0xxxxxxx
if ( $code < 224 )
$bytesnumber = 2 ; // 110xxxxx
else if ( $code < 240 )
$bytesnumber = 3 ; // 1110xxxx
else if ( $code < 248 )
$bytesnumber = 4 ; // 11110xxx
$codetemp = $code - 192 - ( $bytesnumber > 2 ? 32 : 0 ) - ( $bytesnumber > 3 ? 16 : 0 );
for ( $i = 2 ; $i <= $bytesnumber ; $i ++ ) {
$offset ++ ;
$code2 = ord ( substr ( $string , $offset , 1 )) - 128 ; //10xxxxxx
$codetemp = $codetemp * 64 + $code2 ;
}
$code = $codetemp ;
}
$offset += 1 ;
if ( $offset >= strlen ( $string ))
$offset = - 1 ;
return $code ;
}
function strip_combining_chars ( $str ) {
$chars = preg_split ( '//u' , $str , - 1 , PREG_SPLIT_NO_EMPTY );
$str = '' ;
2013-07-29 02:46:00 +02:00
foreach ( $chars as $char ) {
$o = 0 ;
$ord = ordutf8 ( $char , $o );
2013-07-29 02:33:26 +02:00
if ( $ord >= 768 && $ord <= 879 )
continue ;
if ( $ord >= 7616 && $ord <= 7679 )
continue ;
if ( $ord >= 8400 && $ord <= 8447 )
continue ;
if ( $ord >= 65056 && $ord <= 65071 )
continue ;
$str .= $char ;
}
return $str ;
}
function buildThread ( $id , $return = false , $mod = false ) {
2012-04-11 18:49:22 +02:00
global $board , $config ;
$id = round ( $id );
2011-04-13 12:02:58 +02:00
2012-04-12 16:18:19 +02:00
if ( event ( 'build-thread' , $id ))
2012-04-11 18:49:22 +02:00
return ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ] && ! $mod ) {
2012-04-11 18:49:22 +02:00
// Clear cache
cache :: delete ( " thread_index_ { $board [ 'uri' ] } _ { $id } " );
cache :: delete ( " thread_ { $board [ 'uri' ] } _ { $id } " );
2011-04-13 12:02:58 +02:00
}
2012-04-11 18:49:22 +02:00
$query = prepare ( sprintf ( " SELECT * FROM `posts_%s` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id` " , $board [ 'uri' ]));
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
while ( $post = $query -> fetch ()) {
if ( ! isset ( $thread )) {
2012-04-11 18:49:22 +02:00
$thread = new Thread (
$post [ 'id' ], $post [ 'subject' ], $post [ 'email' ], $post [ 'name' ], $post [ 'trip' ], $post [ 'capcode' ], $post [ 'body' ], $post [ 'time' ],
$post [ 'thumb' ], $post [ 'thumbwidth' ], $post [ 'thumbheight' ], $post [ 'file' ], $post [ 'filewidth' ], $post [ 'fileheight' ], $post [ 'filesize' ],
$post [ 'filename' ], $post [ 'ip' ], $post [ 'sticky' ], $post [ 'locked' ], $post [ 'sage' ], $post [ 'embed' ], $mod ? '?/' : $config [ 'root' ], $mod
);
2010-11-02 11:57:33 +01:00
} else {
2012-04-11 18:49:22 +02:00
$thread -> add ( new Post (
$post [ 'id' ], $thread -> id , $post [ 'subject' ], $post [ 'email' ], $post [ 'name' ], $post [ 'trip' ], $post [ 'capcode' ], $post [ 'body' ],
$post [ 'time' ], $post [ 'thumb' ], $post [ 'thumbwidth' ], $post [ 'thumbheight' ], $post [ 'file' ], $post [ 'filewidth' ], $post [ 'fileheight' ],
$post [ 'filesize' ], $post [ 'filename' ], $post [ 'ip' ], $post [ 'embed' ], $mod ? '?/' : $config [ 'root' ], $mod )
);
2010-11-02 11:57:33 +01:00
}
}
2012-04-11 18:49:22 +02:00
// Check if any posts were found
2012-04-12 16:18:19 +02:00
if ( ! isset ( $thread ))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'nonexistant' ]);
$body = Element ( 'thread.html' , array (
2013-07-16 08:48:20 +02:00
'board' => $board ,
'thread' => $thread ,
'body' => $thread -> build (),
2012-04-11 18:49:22 +02:00
'config' => $config ,
'id' => $id ,
'mod' => $mod ,
2012-04-12 13:56:01 +02:00
'antibot' => $mod ? false : create_antibot ( $board [ 'uri' ], $id ),
2012-04-11 18:49:22 +02:00
'boardlist' => createBoardlist ( $mod ),
'return' => ( $mod ? '?' . $board [ 'url' ] . $config [ 'file_index' ] : $config [ 'root' ] . $board [ 'uri' ] . '/' . $config [ 'file_index' ])
));
2012-08-30 17:35:27 +02:00
2012-04-12 16:18:19 +02:00
if ( $return )
2012-04-11 18:49:22 +02:00
return $body ;
2012-08-30 17:35:27 +02:00
file_write ( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . sprintf ( $config [ 'file_page' ], $id ), $body );
2012-04-11 18:49:22 +02:00
}
function rrmdir ( $dir ) {
if ( is_dir ( $dir )) {
$objects = scandir ( $dir );
foreach ( $objects as $object ) {
if ( $object != " . " && $object != " .. " ) {
if ( filetype ( $dir . " / " . $object ) == " dir " )
rrmdir ( $dir . " / " . $object );
else
file_unlink ( $dir . " / " . $object );
2010-11-04 05:40:39 +01:00
}
}
2012-04-11 18:49:22 +02:00
reset ( $objects );
rmdir ( $dir );
2010-11-04 05:40:39 +01:00
}
2012-04-11 18:49:22 +02:00
}
2010-11-04 05:40:39 +01:00
2012-04-11 18:49:22 +02:00
function poster_id ( $ip , $thread ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $id = event ( 'poster-id' , $ip , $thread ))
2012-04-11 18:49:22 +02:00
return $id ;
// Confusing, hard to brute-force, but simple algorithm
return substr ( sha1 ( sha1 ( $ip . $config [ 'secure_trip_salt' ] . $thread ) . $config [ 'secure_trip_salt' ]), 0 , $config [ 'poster_id_length' ]);
}
2010-11-02 11:57:33 +01:00
2012-04-11 18:49:22 +02:00
function generate_tripcode ( $name ) {
global $config ;
2011-07-12 12:29:35 +02:00
2012-04-12 16:18:19 +02:00
if ( $trip = event ( 'tripcode' , $name ))
2012-04-11 18:49:22 +02:00
return $trip ;
2011-02-19 09:45:54 +01:00
2012-04-12 16:18:19 +02:00
if ( ! preg_match ( '/^([^#]+)?(##|#)(.+)$/' , $name , $match ))
2012-04-11 18:49:22 +02:00
return array ( $name );
$name = $match [ 1 ];
$secure = $match [ 2 ] == '##' ;
$trip = $match [ 3 ];
// convert to SHIT_JIS encoding
$trip = mb_convert_encoding ( $trip , 'Shift_JIS' , 'UTF-8' );
// generate salt
$salt = substr ( $trip . 'H..' , 1 , 2 );
$salt = preg_replace ( '/[^\.-z]/' , '.' , $salt );
$salt = strtr ( $salt , ':;<=>?@[\]^_`' , 'ABCDEFGabcdef' );
2012-04-12 16:18:19 +02:00
if ( $secure ) {
if ( isset ( $config [ 'custom_tripcode' ][ " ## { $trip } " ]))
2012-04-11 18:49:22 +02:00
$trip = $config [ 'custom_tripcode' ][ " ## { $trip } " ];
else
$trip = '!!' . substr ( crypt ( $trip , $config [ 'secure_trip_salt' ]), - 10 );
} else {
2012-04-12 16:18:19 +02:00
if ( isset ( $config [ 'custom_tripcode' ][ " # { $trip } " ]))
2012-04-11 18:49:22 +02:00
$trip = $config [ 'custom_tripcode' ][ " # { $trip } " ];
else
$trip = '!' . substr ( crypt ( $trip , $salt ), - 10 );
}
return array ( $name , $trip );
}
// Highest common factor
function hcf ( $a , $b ){
$gcd = 1 ;
if ( $a > $b ) {
$a = $a + $b ;
$b = $a - $b ;
$a = $a - $b ;
}
if ( $b == ( round ( $b / $a )) * $a )
$gcd = $a ;
else {
2012-04-12 16:18:19 +02:00
for ( $i = round ( $a / 2 ); $i ; $i -- ) {
2012-04-11 18:49:22 +02:00
if ( $a == round ( $a / $i ) * $i && $b == round ( $b / $i ) * $i ) {
$gcd = $i ;
$i = false ;
}
2011-02-19 09:45:54 +01:00
}
}
2012-04-11 18:49:22 +02:00
return $gcd ;
}
function fraction ( $numerator , $denominator , $sep ) {
$gcf = hcf ( $numerator , $denominator );
$numerator = $numerator / $gcf ;
$denominator = $denominator / $gcf ;
2011-02-19 09:45:54 +01:00
2012-04-11 18:49:22 +02:00
return " { $numerator } { $sep } { $denominator } " ;
}
function getPostByHash ( $hash ) {
global $board ;
$query = prepare ( sprintf ( " SELECT `id`,`thread` FROM `posts_%s` WHERE `filehash` = :hash " , $board [ 'uri' ]));
$query -> bindValue ( ':hash' , $hash , PDO :: PARAM_STR );
$query -> execute () or error ( db_error ( $query ));
2012-04-12 16:18:19 +02:00
if ( $post = $query -> fetch ()) {
2012-04-11 18:49:22 +02:00
return $post ;
2011-02-19 09:28:07 +01:00
}
2011-11-16 09:59:21 +01:00
2012-04-11 18:49:22 +02:00
return false ;
}
2012-11-14 21:33:27 +01:00
function getPostByHashInThread ( $hash , $thread ) {
global $board ;
$query = prepare ( sprintf ( " SELECT `id`,`thread` FROM `posts_%s` WHERE `filehash` = :hash AND ( `thread` = :thread OR `id` = :thread ) " , $board [ 'uri' ]));
$query -> bindValue ( ':hash' , $hash , PDO :: PARAM_STR );
$query -> bindValue ( ':thread' , $thread , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
if ( $post = $query -> fetch ()) {
return $post ;
}
return false ;
}
2012-04-11 18:49:22 +02:00
function undoImage ( array $post ) {
2012-04-12 16:18:19 +02:00
if ( ! $post [ 'has_file' ])
2012-04-11 18:49:22 +02:00
return ;
2012-04-12 16:18:19 +02:00
if ( isset ( $post [ 'file' ]))
2012-04-11 18:49:22 +02:00
file_unlink ( $post [ 'file' ]);
2012-04-12 16:18:19 +02:00
if ( isset ( $post [ 'thumb' ]))
2012-04-11 18:49:22 +02:00
file_unlink ( $post [ 'thumb' ]);
}
function rDNS ( $ip_addr ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ] && ( $host = cache :: get ( 'rdns_' . $ip_addr ))) {
2011-12-03 01:52:31 +01:00
return $host ;
}
2012-04-12 16:18:19 +02:00
if ( ! $config [ 'dns_system' ]) {
2012-04-11 18:49:22 +02:00
$host = gethostbyaddr ( $ip_addr );
} else {
$resp = shell_exec ( 'host -W 1 ' . $ip_addr );
2012-04-12 16:18:19 +02:00
if ( preg_match ( '/domain name pointer ([^\s]+)$/' , $resp , $m ))
2012-04-11 18:49:22 +02:00
$host = $m [ 1 ];
else
$host = $ip_addr ;
2012-03-15 04:00:25 +01:00
}
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-11 18:49:22 +02:00
cache :: set ( 'rdns_' . $ip_addr , $host , 3600 );
return $host ;
}
2012-03-15 04:00:25 +01:00
2012-04-11 18:49:22 +02:00
function DNS ( $host ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ] && ( $ip_addr = cache :: get ( 'dns_' . $host ))) {
2012-04-11 18:49:22 +02:00
return $ip_addr ;
}
2012-04-12 16:18:19 +02:00
if ( ! $config [ 'dns_system' ]) {
2012-04-11 18:49:22 +02:00
$ip_addr = gethostbyname ( $host );
2012-04-12 16:18:19 +02:00
if ( $ip_addr == $host )
2012-04-11 18:49:22 +02:00
$ip_addr = false ;
} else {
$resp = shell_exec ( 'host -W 1 ' . $host );
2012-04-12 16:18:19 +02:00
if ( preg_match ( '/has address ([^\s]+)$/' , $resp , $m ))
2012-04-11 18:49:22 +02:00
$ip_addr = $m [ 1 ];
else
$ip_addr = false ;
}
2012-04-12 16:18:19 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-11 18:49:22 +02:00
cache :: set ( 'dns_' . $host , $ip_addr , 3600 );
return $ip_addr ;
}