Want more features on Pastebin? Sign Up, it's FREE!

4chan source

By: Oloty on Jan 17th, 2014  |  syntax: PHP  |  size: 94.89 KB  |  views: 101,243  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?
  2. /* Credits: Oloty (oloty.me) */
  3. if(file_exists('/www/global/lockdown')) {
  4.         if($_COOKIE['4chan_auser'] && $_COOKIE['4chan_apass'] && ($_POST['mode']=='usrdel'||$_GET['mode']=='latest')) {
  5.                 // ok
  6.         }
  7.         else {
  8.                  die('Posting temporarily disabled. Come back later!<br/>&mdash;Team 4chan (uptime? what\'s that?)');
  9.         }
  10. }
  11. include_once "./yotsuba_config.php";
  12. include("./postfilter.php");
  13. include("./ads.php");
  14. define('SQLLOGBAN', 'banned_users');            //Table (NOT DATABASE) used for holding banned users
  15. define('SQLLOGMOD', 'mod_users');               //Table (NOT DATABASE) used for holding mod users
  16. define('SQLLOGDEL', 'del_log');         //Table (NOT DATABASE) used for holding deletion log
  17.  
  18. if(BOARD_DIR == 'test') {
  19.  ini_set('display_errors', 1);
  20. }
  21. extract($_POST);
  22. extract($_GET);
  23. extract($_COOKIE);
  24.  
  25. $id = intval($id);
  26.  
  27. if(array_key_exists('upfile',$_FILES)) {
  28. $upfile_name=$_FILES["upfile"]["name"];
  29. $upfile=$_FILES["upfile"]["tmp_name"];
  30. }
  31. else {
  32. $upfile_name=$upfile='';
  33. }
  34.  
  35. $path = realpath("./").'/'.IMG_DIR;
  36. ignore_user_abort(TRUE);
  37.  
  38. if(WORD_FILT&&file_exists("wf.php")){include_once("wf.php");}
  39. if(JANITOR_BOARD == 1)
  40.         include_once '/www/global/plugins/broomcloset.php';
  41.  
  42. //mysql_board_connect();
  43.  
  44. // truncate $str to $max_lines lines and return $str and $abbr
  45. // where $abbr = whether or not $str was actually truncated
  46. function abbreviate($str,$max_lines) {
  47.         if(!defined('MAX_LINES_SHOWN')) {
  48.                 if(defined('BR_CHECK')) {
  49.                 define('MAX_LINES_SHOWN', BR_CHECK);
  50.                 } else {
  51.                 define('MAX_LINES_SHOWN', 20);
  52.                 }
  53.                 $max_lines = MAX_LINES_SHOWN;
  54.         }
  55.         $lines = explode("<br />", $str);
  56.         if(count($lines) > $max_lines) {
  57.                 $abbr = 1;
  58.                 $lines = array_slice($lines, 0, $max_lines);
  59.                 $str = implode("<br />", $lines);
  60.         } else {
  61.                 $abbr = 0;
  62.         }
  63.        
  64.         //close spans after abbreviating
  65.         //XXX will not work with more html - use abbreviate_html from shiichan
  66.         $str .= str_repeat("</span>", substr_count($str, "<span") - substr_count($str, "</span"));
  67.        
  68.         return array($str, $abbr);
  69. }
  70.  
  71.  
  72. // print $contents to $filename by using a temporary file and renaming it
  73. // (makes *.html and *.gz if USE_GZIP is on)
  74. function print_page($filename,$contents,$force_nogzip=0) {
  75.         $gzip = (USE_GZIP == 1 && !$force_nogzip);
  76.         $tempfile = tempnam(realpath(RES_DIR), "tmp"); //note: THIS actually creates the file
  77.         file_put_contents($tempfile, $contents, FILE_APPEND);
  78.         rename($tempfile, $filename);
  79.         chmod($filename, 0664); //it was created 0600
  80.  
  81.         if($gzip) {    
  82.                 $tempgz = tempnam(realpath(RES_DIR), "tmp"); //note: THIS actually creates the file
  83.                 $gzfp = gzopen($tempgz, "w");
  84.                 gzwrite($gzfp, $contents);
  85.                 gzclose($gzfp);
  86.                 rename($tempgz, $filename . '.gz');
  87.                 chmod($filename . '.gz', 0664); //it was created 0600
  88.         }
  89. }
  90.  
  91. function file_get_contents_cached($filename) {
  92.         static $cache = array();
  93.         if(isset($cache[$filename]))
  94.                 return $cache[$filename];
  95.         //$cache[$filename] = file_get_contents($filename);
  96.         return $cache[$filename];
  97. }
  98.        
  99. function blotter_contents() {
  100.         static $cache;
  101.         if(isset($cache)) return $cache;
  102.         $ret = "";
  103.         $topN = 4; //how many lines to print
  104.         $bl_lines = file( BLOTTER_PATH );
  105.         $bl_top = array_slice($bl_lines, 0, $topN);
  106.         $date = "";
  107.         foreach($bl_top as $line) {
  108.                         if(!$date) {
  109.                                 $lineparts = explode(' - ', $line);
  110.                                 if(strpos($lineparts[0],'<font')!==FALSE) {
  111.                                         $dateparts = explode('>', $lineparts[0]);
  112.                                         $date = $dateparts[1];
  113.                                         $date = "<li><font color=\"red\">Blotter updated: $date</font>";
  114.                                 }
  115.                                 else {
  116.                                         $date = $lineparts[0];
  117.                                         $date = "<li>Blotter updated: $date";
  118.                                 }
  119.                         }
  120.                         $line = trim($line);
  121.                         $line = str_replace("\\", "\\\\", $line);
  122.                         $line = str_replace("'", "\'", $line);
  123.                         $ret .= "'<li>$line'+\n";
  124.         }
  125.         $ret .= "''";
  126.         $cache = array($date,$ret);
  127.         return array($date,$ret);
  128. }
  129.  
  130. // insert into the rapidsearch queue
  131. function rapidsearch_insert($board, $no, $body) {
  132.         $board = mysql_real_escape_string($board);
  133.         $no = (int)$no;
  134.         $body = mysql_real_escape_string($body);
  135.         mysql_global_do("INSERT INTO rs.rsqueue (`board`,`no`,`ts`,`com`) VALUES ('$board',$no,NOW(),'$body')");
  136. }
  137.  
  138. function find_match_and_prefix($regex, $str, $off, &$match)
  139. {
  140.         if (!preg_match($regex, $str, $m, PREG_OFFSET_CAPTURE, $off)) return FALSE;
  141.        
  142.         $moff = $m[0][1];
  143.         $match = array(substr($str, $off, $moff-$off), $m[0][0]);
  144.  
  145.         return TRUE;
  146. }
  147.  
  148. function spoiler_parse($com) {
  149.         if (!find_match_and_prefix("/\[spoiler\]/", $com, 0, $m)) return $com;
  150.        
  151.         $bl = strlen("[spoiler]"); $el = $bl+1;
  152.         $st = '<span class="spoiler" onmouseover="this.style.color=\'#FFF\';" onmouseout="this.style.color=this.style.backgroundColor=\'#000\'" style="color:#000;background:#000">';
  153.         $et = '</span>';
  154.         $ret = $m[0].$st; $lev = 1;
  155.         $off = strlen($m[0]) + $bl;
  156.        
  157.         while (1) {
  158.                 if (!find_match_and_prefix("@\[/?spoiler\]@", $com, $off, $m)) break;
  159.                 list($txt, $tag) = $m;
  160.                
  161.                 $ret .= $txt;
  162.                 $off += strlen($txt) + strlen($tag);
  163.                
  164.                 if ($tag == "[spoiler]") {
  165.                         $ret .= $st;
  166.                         $lev++;
  167.                 } else if ($lev) {
  168.                         $ret .= $et;
  169.                         $lev--;
  170.                 }
  171.         }
  172.        
  173.         $ret .= substr($com, $off, strlen($com)-$off);
  174.         $ret .= str_repeat($et, $lev);
  175.  
  176.         return $ret;
  177. }
  178.  
  179. //rebuild the bans in array $boards
  180. function rebuild_bans($boards) {
  181.     $cmd = "nohup /usr/local/bin/suid_run_global bin/rebuildbans $boards >/dev/null 2>&1 &";
  182.         exec($cmd);
  183. }
  184.  
  185. function append_ban($board, $ip) {
  186.     $cmd = "nohup /usr/local/bin/suid_run_global bin/appendban $board $ip >/dev/null 2>&1 &";
  187.         exec($cmd);
  188. }
  189.  
  190. // check whether the current user can perform $action (on $no, for some actions)
  191. // board-level access is cached in $valid_cache.
  192. function valid($action='moderator', $no=0){
  193.         static $valid_cache; // the access level of the user
  194.         $access_level = array('none' => 0, 'janitor' => 1, 'janitor_this_board' => 2, 'moderator' => 5, 'manager' => 10, 'admin' => 20);
  195.         if(!isset($valid_cache)) {
  196.                 $valid_cache = $access_level['none'];
  197.                 if(isset($_COOKIE['4chan_auser'])&&isset($_COOKIE['4chan_apass'])){
  198.                         $user = mysql_real_escape_string($_COOKIE['4chan_auser']);
  199.                         $pass = mysql_real_escape_string($_COOKIE['4chan_apass']);
  200.                 }
  201.                 if($user&&$pass) {
  202.                         $result=mysql_global_call("SELECT allow,deny FROM ".SQLLOGMOD." WHERE username='$user' and password='$pass'");
  203.                         list($allow,$deny) = mysql_fetch_row($result);
  204.                         mysql_free_result($result);
  205.                         if($allow) {
  206.                                 $allows = explode(',', $allow);
  207.                                 $seen_janitor_token = false;
  208.                                 // each token can increase the access level,
  209.                                 // except that we only know that they're a moderator or a janitor for another board
  210.                                 // AFTER we read all the tokens
  211.                                 foreach($allows as $token) {
  212.                                         if($token == 'janitor')
  213.                                                 $seen_janitor_token = true;
  214.                                         else if($token == 'manager' && $valid_cache < $access_level['manager'])
  215.                                                 $valid_cache = $access_level['manager'];
  216.                                         else if($token == 'admin' && $valid_cache < $access_level['admin'])
  217.                                                 $valid_cache = $access_level['admin'];
  218.                                         else if(($token == BOARD_DIR || $token == 'all') && $valid_cache < $access_level['janitor_this_board'])
  219.                                                 $valid_cache = $access_level['janitor_this_board']; // or could be moderator, will be increased in next step
  220.                                 }
  221.                                 // now we can set moderator or janitor status
  222.                                 if(!$seen_janitor_token) {
  223.                                         if($valid_cache < $access_level['moderator'])
  224.                                                 $valid_cache = $access_level['moderator'];
  225.                                 }
  226.                                 else {
  227.                                         if($valid_cache < $access_level['janitor'])
  228.                                                 $valid_cache = $access_level['janitor'];
  229.                                 }
  230.                                 if($deny) {
  231.                                         $denies = explode(',', $deny);
  232.                                         if(in_array(BOARD_DIR,$denies)) {
  233.                                                 $valid_cache = $access_level['none'];
  234.                                         }
  235.                                 }
  236.                         }
  237.                 }
  238.         }
  239.         switch($action) {
  240.                 case 'moderator':
  241.                         return $valid_cache >= $access_level['moderator'];
  242.                 case 'textonly':
  243.                         return $valid_cache >= $access_level['moderator'];
  244.                 case 'janitor_board':
  245.                         return $valid_cache >= $access_level['janitor'];
  246.                 case 'delete':
  247.                         if($valid_cache >= $access_level['janitor_this_board']) {
  248.                                 return true;
  249.                         }
  250.                         // if they're a janitor on another board, check for illegal post unlock                
  251.                         else if($valid_cache >= $access_level['janitor']) {
  252.                                 $query=mysql_global_do("SELECT COUNT(*) from reports WHERE board='".BOARD_DIR."' AND no=$no AND cat=2");
  253.                                 $illegal_count = mysql_result($query, 0, 0);
  254.                                 mysql_free_result($query);
  255.                                 return $illegal_count >= 3;
  256.                         }
  257.                 case 'reportflood':
  258.                         return $valid_cache >= $access_level['janitor'];
  259.                 case 'floodbypass':
  260.                         return $valid_cache >= $access_level['moderator'];
  261.                 default: // unsupported action
  262.                         return false;
  263.         }
  264. }
  265.  
  266. function sticky_post($no, $position) {
  267.         global $log; log_cache();
  268.         $post_sticknum="202701010000".sprintf("%02d",$position);
  269.         $log[$no]['root'] = $post_sticknum;
  270.         $log[$no]['sticky'] = '1';
  271.         mysql_board_call('UPDATE '.SQLLOG." SET sticky='1'".
  272.                                 ", root='".$post_sticknum."'".
  273.                                 " WHERE no='".mysql_real_escape_string($no)."'");
  274. }
  275.  
  276. function permasage_post($no) {
  277.         global $log; log_cache();
  278.         $log[$no]['permasage'] = '1';
  279.         mysql_board_call('UPDATE '.SQLLOG." SET permasage='1'".
  280.                                 " WHERE no='".mysql_real_escape_string($no)."'");
  281. }
  282.  
  283. function rebuildqueue_create_table() {
  284.         $sql = <<<EOSQL
  285. CREATE TABLE `rebuildqueue` (
  286.   `board` char(4) NOT NULL,
  287.   `no` int(11) NOT NULL,
  288.   `ownedby` int(11) NOT NULL default '0',
  289.   `ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  290.   PRIMARY KEY  (`board`,`no`,`ownedby`)
  291. )
  292. EOSQL;
  293.         mysql_board_call($sql);
  294. }
  295.  
  296. function rebuildqueue_add($no) {
  297.         $board = BOARD_DIR;
  298.         $no = (int)$no;
  299.         for($i=0;$i<2;$i++)
  300.                 if(!mysql_board_call("INSERT IGNORE INTO rebuildqueue (board,no) VALUES ('$board','$no')"))
  301.                         rebuildqueue_create_table();
  302.                 else
  303.                         break;
  304. }
  305.  
  306. function rebuildqueue_remove($no) {
  307.         $board = BOARD_DIR;
  308.         $no = (int)$no;
  309.         for($i=0;$i<2;$i++)
  310.                 if(!mysql_board_call("DELETE FROM rebuildqueue WHERE board='$board' AND no='$no'"))
  311.                         rebuildqueue_create_table();
  312.                 else
  313.                         break;
  314. }
  315.  
  316. function rebuildqueue_take_all() {
  317.         $board = BOARD_DIR;
  318.         $uid = mt_rand(1, mt_getrandmax());
  319.         for($i=0;$i<2;$i++)
  320.                 if(!mysql_board_call("UPDATE rebuildqueue SET ownedby=$uid,ts=ts WHERE board='$board' AND ownedby=0"))
  321.                         rebuildqueue_create_table();
  322.                 else
  323.                         break;
  324.         $q = mysql_board_call("SELECT no FROM rebuildqueue WHERE board='$board' AND ownedby=$uid");
  325.         $posts = array();
  326.         while($post=mysql_fetch_assoc($q))
  327.                 $posts[] = $post['no'];
  328.         return $posts;
  329. }
  330.  
  331. function iplog_add($board, $no, $ip) {
  332.         $board = mysql_real_escape_string($board);
  333.         $no = (int)$no;
  334.         $ip = mysql_real_escape_string($ip);
  335.         mysql_board_call("INSERT INTO iplog (board,no,ip) VALUES ('$board',$no,'$ip')");
  336. }
  337. // build a structure out of all the posts in the database.
  338. // this lets us replace a LOT of queries with a simple array access.
  339. // it only builds the first time it was called.
  340. // rather than calling log_cache(1) to rebuild everything,
  341. // you should just manipulate the structure directly.
  342. function log_cache($invalidate=0) {
  343.         global $log, $ipcount, $mysql_unbuffered_reads, $lastno;
  344.         $ips = array();
  345.         $threads = array(); // no's
  346.         if($invalidate==0 && isset($log)) return;
  347.         $log = array(); // no -> [ data ]
  348.         //mysql_board_call("SET read_buffer_size=1048576");
  349.         $mysql_unbuffered_reads = 1;
  350.         //$query = mysql_board_call("SELECT * FROM ".SQLLOG);
  351.         $offset = 0;
  352.         $lastno = 0;
  353.         //while($row = mysql_fetch_assoc($query)) {
  354.                 if($row['no'] > $lastno) $lastno = $row['no'];
  355.                 $ips[$row['host']] = 1;
  356.                 // initialize log row if necessary
  357.                 if( !isset($log[$row['no']]) ) {
  358.                         $log[$row['no']] = $row;
  359.                         $log[$row['no']]['children'] = array();
  360.                 } else { // otherwise merge it with $row
  361.                         foreach($row as $key=>$val)
  362.                                 $log[$row['no']][$key] = $val;
  363.                 }
  364.                 // if this is a reply
  365.                 if($row['resto']) {
  366.                         // initialize whatever we need to
  367.                         if( !isset($log[$row['resto']]) )
  368.                         //      $log[$row['resto']] = array();
  369.                         if( !isset($log[$row['resto']]['children']) )
  370.                                 $log[$row['resto']]['children'] = array();
  371.                                
  372.                         // add this post to list of children
  373.                         $log[$row['resto']]['children'][$row['no']] = 1;
  374.                         if($row['fsize']) {
  375.                                 if(!isset($log[$row['resto']]['imgreplycount']))
  376.                                         $log[$row['resto']]['imgreplycount'] = 0;
  377.                                 else
  378.                                         $log[$row['resto']]['imgreplycount']++;
  379.                         }
  380.                 } /*else {
  381.                         $threads[] = $row['no'];
  382.                 }*/
  383.         }
  384.        
  385.         //$query = mysql_board_call("SELECT no FROM ".SQLLOG." WHERE root>0 order by root desc");
  386.         while($row = mysql_fetch_assoc($query)) {
  387.                 if(isset($log[$row['no']]) && $log[$row['no']]['resto']==0)
  388.                         $threads[] = $row['no'];
  389.         }
  390.         $log['THREADS'] = $threads;
  391.         $mysql_unbuffered_reads = 0;
  392.        
  393.         // calculate old-status for PAGE_MAX mode
  394.         if(EXPIRE_NEGLECTED != 1) {
  395.                 rsort($threads, SORT_NUMERIC);
  396.        
  397.                 $threadcount = count($threads);
  398.                 if(PAGE_MAX > 0) // the lowest 5% of maximum threads get marked old
  399.                         for($i = floor(0.95*PAGE_MAX*PAGE_DEF); $i < $threadcount; $i++) {
  400.                                 if(!$log[$threads[$i]]['sticky'] && EXPIRE_NEGLECTED != 1)
  401.                                         $log[$threads[$i]]['old'] = 1;
  402.                         }
  403.                 else { // threads w/numbers below 5% of LOG_MAX get marked old
  404.                         foreach($threads as $thread) {
  405.                                 if($lastno-LOG_MAX*0.95>$thread)
  406.                                         if(!$log[$thread]['sticky'])
  407.                                                 $log[$thread]['old'] = 1;                              
  408.                         }
  409.                 }
  410.         }
  411.        
  412.         $ipcount = count($ips);
  413. //}
  414.  
  415.  
  416. // deletes a post from the database
  417. // imgonly: whether to just delete the file or to delete from the database as well
  418. // automatic: always delete regardless of password/admin (for self-pruning)
  419. // children: whether to delete just the parent post of a thread or also delete the children
  420. // die: whether to die on error
  421. // careful, setting children to 0 could leave orphaned posts.
  422. function delete_post($resno, $pwd, $imgonly=0, $automatic=0, $children=1, $die=1) {
  423.         global $log, $path;
  424.         log_cache();
  425.         $resno = intval($resno);
  426.  
  427.         // get post info
  428.         if(!isset($log[$resno])){if ($die) error("Can't find the post $resno.");}
  429.         $row=$log[$resno];
  430.        
  431.         // check password- if not ok, check admin status (and set $admindel if allowed)
  432.         $delete_ok = ( $automatic || (substr(md5($pwd),2,8) == $row['pwd']) || ($row['host'] == $_SERVER['REMOTE_ADDR']) );
  433.         if( ($pwd==ADMIN_PASS || $pwd==ADMIN_PASS2) ) { $delete_ok = $admindel = valid('delete', $resno); }
  434.         if(!$delete_ok) error(S_BADDELPASS);
  435.  
  436.         // check ghost bumping
  437.         if(!isset($admindel) || !$admindel) {
  438.                 if(BOARD_DIR == 'a' && (int)$row['time'] > (time() - 25) && $row['email'] != 'sage') {
  439.                         $ghostdump = var_export(array(
  440.                                 'server'=>$_SERVER,
  441.                                 'post'=>$_POST,
  442.                                 'cookie'=>$_COOKIE,
  443.                                 'row'=>$row),true);
  444.                         //file_put_contents('ghostbump.'.time(),$ghostdump);
  445.                 }
  446.         }
  447.  
  448.         if(isset($admindel) && $admindel) { // extra actions for admin user
  449.                 $auser = mysql_escape_string($_COOKIE['4chan_auser']);
  450.                 $adfsize=($row['fsize']>0)?1:0;
  451.                 $adname=str_replace('</span> <span class="postertrip">!','#',$row['name']);
  452.                 if($imgonly) { $imgonly=1; } else { $imgonly=0; }
  453.                 $row['sub'] = mysql_escape_string($row['sub']);
  454.                 $row['com'] = mysql_escape_string($row['com']);
  455.                 $row['filename'] = mysql_escape_string($row['filename']);
  456.                 mysql_global_do("INSERT INTO ".SQLLOGDEL." (imgonly,postno,board,name,sub,com,img,filename,admin) values('$imgonly','$resno','".SQLLOG."','$adname','{$row['sub']}','{$row['com']}','$adfsize','{$row['filename']}','$auser')");       
  457.         }
  458.        
  459.         if($row['resto']==0 && $children && !$imgonly) // select thread and children
  460.                 $result=mysql_board_call("select no,resto,tim,ext from ".SQLLOG." where no=$resno or resto=$resno");
  461.         else // just select the post
  462.                 $result=mysql_board_call("select no,resto,tim,ext from ".SQLLOG." where no=$resno");
  463.        
  464.         while($delrow=mysql_fetch_array($result)) {
  465.                 // delete
  466.                 $delfile = $path.$delrow['tim'].$delrow['ext']; //path to delete
  467.                 $delthumb = THUMB_DIR.$delrow['tim'].'s.jpg';
  468.                 if(is_file($delfile)) unlink($delfile); // delete image
  469.                 if(is_file($delthumb)) unlink($delthumb); // delete thumb
  470.                 if(OEKAKI_BOARD == 1 && is_file($path.$delrow['tim'].'.pch'))
  471.                         unlink($path.$delrow['tim'].'.pch'); // delete oe animation
  472.                 if(!$imgonly){ // delete thread page & log_cache row
  473.                         if($delrow['resto'])
  474.                                 unset( $log[$delrow['resto']]['children'][$delrow['no']] );
  475.                         unset( $log[$delrow['no']] );
  476.                         $log['THREADS'] = array_diff($log['THREADS'], array($delrow['no'])); // remove from THREADS
  477.                         mysql_global_do("DELETE FROM reports WHERE no=".$delrow['no']); // clear reports
  478.                         if(USE_GZIP == 1) {
  479.                                 @unlink(RES_DIR.$delrow['no'].PHP_EXT);
  480.                                 @unlink(RES_DIR.$delrow['no'].PHP_EXT.'.gz');
  481.                         }
  482.                         else {
  483.                                 @unlink(RES_DIR.$delrow['no'].PHP_EXT);
  484.                         }
  485.                 }
  486.         }
  487.  
  488.         //delete from DB
  489.         if($row['resto']==0 && $children && !$imgonly) // delete thread and children
  490.                 $result=mysql_board_call("delete from ".SQLLOG." where no=$resno or resto=$resno");
  491.         elseif(!$imgonly) // just delete the post
  492.                 $result=mysql_board_call("delete from ".SQLLOG." where no=$resno");
  493.                        
  494.         return $row['resto']; // so the caller can know what pages need to be rebuilt
  495. }
  496.  
  497. // purge old posts
  498. // should be called whenever a new post is added.
  499. function trim_db() {
  500.         if(JANITOR_BOARD == 1) return;
  501.        
  502.         log_cache();
  503.        
  504.         $maxposts = LOG_MAX;
  505.         // max threads = max pages times threads-per-page
  506.         $maxthreads = (PAGE_MAX > 0)?(PAGE_MAX * PAGE_DEF):0;
  507.        
  508.         // New max-page method
  509.         if($maxthreads) {
  510.                 $exp_order = 'no';
  511.                 if(EXPIRE_NEGLECTED == 1) $exp_order = 'root';
  512.                 logtime('trim_db before select threads');
  513.                 $result = mysql_board_call("SELECT no FROM ".SQLLOG." WHERE sticky=0 AND resto=0 ORDER BY $exp_order ASC");
  514.                 logtime('trim_db after select threads');
  515.                 $threadcount = mysql_num_rows($result);
  516.                 while($row=mysql_fetch_array($result) and $threadcount >= $maxthreads) {
  517.                         delete_post($row['no'], 'trim', 0, 1); // imgonly=0, automatic=1, children=1
  518.                         $threadcount--;
  519.                 }
  520.                 mysql_free_result($result);
  521.         // Original max-posts method (note: cleans orphaned posts later than parent posts)
  522.         } else {
  523.                 // make list of stickies
  524.                 $stickies = array(); // keys are stickied thread numbers
  525.                 $result = mysql_board_call("SELECT no from ".SQLLOG." where sticky=1 and resto=0");
  526.                 while($row=mysql_fetch_array($result)) {
  527.                         $stickies[ $row['no'] ] = 1;
  528.                 }
  529.                
  530.                 $result = mysql_board_call("SELECT no,resto,sticky FROM ".SQLLOG." ORDER BY no ASC");
  531.                 $postcount = mysql_num_rows($result);
  532.                 while($row=mysql_fetch_array($result) and $postcount >= $maxposts) {
  533.                         // don't delete if this is a sticky thread
  534.                         if($row['sticky'] == 1) continue;
  535.                         // don't delete if this is a REPLY to a sticky
  536.                         if($row['resto'] != 0 && $stickies[ $row['resto'] ] == 1) continue;
  537.                         delete_post($row['no'], 'trim', 0, 1, 0); // imgonly=0, automatic=1, children=0
  538.                         $postcount--;
  539.                 }
  540.                 mysql_free_result($result);
  541.         }
  542.  
  543. }
  544.  
  545. //resno - thread page to update (no of thread OP)
  546. //rebuild - don't rebuild page indexes
  547. function updatelog($resno=0,$rebuild=0){
  548.   global $log,$path;
  549.         set_time_limit(60);
  550. if($_SERVER['REQUEST_METHOD']=='GET' && !valid()) die(''); // anti ddos
  551.         log_cache();
  552.        
  553.           $imgdir = ((USE_SRC_CGI==1)?str_replace('src','src.cgi',IMG_DIR2):IMG_DIR2);
  554.         if(defined('INTERSTITIAL_LINK')) $imgdir .= INTERSTITIAL_LINK;
  555.           $thumbdir = THUMB_DIR2;
  556.                 $imgurl = DATA_SERVER;
  557.  
  558.  
  559.   $resno=(int)$resno;
  560.   if($resno){
  561.         if(!isset($log[$resno])) {
  562.                 updatelog(0,$rebuild); // the post didn't exist, just rebuild the indexes
  563.                 return;
  564.         }
  565.         else if($log[$resno]['resto']) {
  566.                         updatelog($log[$resno]['resto'],$rebuild); // $resno is a reply, try rebuilding the parent
  567.                         return;
  568.                 }
  569.   }
  570.  
  571.   if($resno){
  572.         $treeline = array($resno); logtime("Formatting thread page");
  573.     //if(!$treeline=mysql_board_call("select * from ".SQLLOG." where root>0 and no=".$resno." order by root desc")){echo S_SQLFAIL;}
  574.   }else{
  575.         $treeline = $log['THREADS']; logtime("Formatting index page");
  576.     //if(!$treeline=mysql_board_call("select * from ".SQLLOG." where root>0 order by root desc")){echo S_SQLFAIL;}
  577.   }
  578.  
  579.  
  580.         $counttree=count($treeline);
  581.   //$counttree=mysql_num_rows($treeline);
  582.   if(!$counttree){
  583.     $logfilename=PHP_SELF2;
  584.     $dat='';
  585.     head($dat,$resno);
  586.     form($dat,$resno);
  587.     print_page($logfilename, $dat);
  588.   }
  589.  
  590.         if(UPDATE_THROTTLING >= 1) {
  591.           $update_start = time();
  592.           touch("updatelog.stamp", $update_start);
  593.           $low_priority = false;
  594.           clearstatcache();
  595.           if(@filemtime(PHP_SELF) > $update_start-UPDATE_THROTTLING) {
  596.                 $low_priority = true;
  597.                 //touch($update_start . ".lowprio");
  598.           }
  599.           else {
  600.                 touch(PHP_SELF,$update_start);
  601.           }
  602.          //     $mt = @filemtime(PHP_SELF);
  603.         //      touch($update_start . ".$mt.highprio");
  604.         }
  605.        
  606.         // if we're using CACHE_TTL method
  607.         if(CACHE_TTL >= 1) {
  608.                 if($resno) {
  609.                         $logfilename = RES_DIR.$resno.PHP_EXT;
  610.                 }
  611.                 else {
  612.                         $logfilename = PHP_SELF2;
  613.                 }
  614.                 //if(USE_GZIP == 1) $logfilename .= '.html';
  615.                 // if the file has been made and it's younger than CACHE_TTL seconds ago
  616.                 clearstatcache();
  617.                 if(file_exists($logfilename) && filemtime($logfilename) > (time() - CACHE_TTL)) {
  618.                         // save the post to be rebuilt later
  619.                         rebuildqueue_add($resno);
  620.                         // if it's a thread, try again on the indexes
  621.                         if($resno && !$rebuild) updatelog();
  622.                         // and we don't do any more rebuilding on this request
  623.                         return true;
  624.                 }
  625.                 else {
  626.                         // we're gonna update it now, so take it out of the queue
  627.                         rebuildqueue_remove($resno);
  628.                         // and make sure nobody else starts trying to update it because it's too old
  629.                         touch($logfilename);
  630.                 }                      
  631.         }
  632.  
  633.   for($page=0;$page<$counttree;$page+=PAGE_DEF){
  634.     $dat='';
  635.     head($dat,$resno);
  636.     form($dat,$resno);
  637.     if(!$resno){
  638.       $st = $page;
  639.     }
  640.     $dat.='<form name="delform" action="';
  641.     $dat.=PHP_SELF_ABS.'" method=POST>';
  642.  
  643.   for($i = $st; $i < $st+PAGE_DEF; $i++){
  644.         if(UPDATE_THROTTLING >= 1) {
  645.                 clearstatcache();
  646.                 if($low_priority && @filemtime("updatelog.stamp") > $update_start) {
  647.                                 //touch($update_start . ".throttled");
  648.                                 return;
  649.                 }
  650.                 if(rand(0,15)==0) return;
  651.          }
  652.        
  653.         list($_unused,$no) = each($treeline);
  654.     //list($no,$sticky,$permasage,$closed,$now,$name,$email,$sub,$com,$host,$pwd,$filename,$ext,$w,$h,$tn_w,$tn_h,$tim,$time,$md5,$fsize,$root,$resto)=mysql_fetch_row($treeline);
  655.     if(!$no){break;}
  656.     extract($log[$no]);
  657.     //if(!$resno&&!file_exists(RES_DIR.$no.PHP_EXT)) { updatelog($no); break; } // uhh
  658.  
  659.         //POST FILTERING
  660.         if(JANITOR_BOARD == 1) {
  661.                 $name = broomcloset_capcode($name);
  662.         }
  663.         if($email) $name = "<a href=\"mailto:$email\" class=\"linkmail\">$name</a>";
  664.     if(strpos($sub,"SPOILER<>")===0) {
  665.         $sub = substr($sub,strlen("SPOILER<>")); //trim out SPOILER<>
  666.         $spoiler = 1;
  667.     } else $spoiler = 0;
  668.     $com = auto_link($com,$resno);
  669.     if(!$resno) list($com,$abbreviated) = abbreviate($com, MAX_LINES_SHOWN);
  670.  
  671.           if(isset($abbreviated) && $abbreviated) $com .= "<br /><span class=\"abbr\">Comment too long. Click <a href=\"".RES_DIR.($resto?$resto:$no).PHP_EXT."#$no\">here</a> to view the full text.</span>";
  672.     // Picture file name
  673.     $img = $path.$tim.$ext;
  674.     $displaysrc = $imgdir.$tim.$ext;
  675.     $linksrc = ((USE_SRC_CGI==1)?(str_replace(".cgi","",$imgdir).$tim.$ext):$displaysrc);
  676.         if(defined('INTERSTITIAL_LINK')) $linksrc = str_replace(INTERSTITIAL_LINK,"",$linksrc);
  677.     $src = IMG_DIR.$tim.$ext;
  678.     $longname = $filename.$ext;
  679.     if (strlen($filename)>40) {
  680.             $shortname = substr($filename, 0, 40)."(...)".$ext;
  681.     } else {
  682.             $shortname = $longname;
  683.     }
  684.     // img tag creation
  685.     $imgsrc = "";
  686.     if($ext){
  687.         // turn the 32-byte ascii md5 into a 24-byte base64 md5
  688.         $shortmd5 = base64_encode(pack("H*", $md5));
  689.       if ($fsize >= 1048576) { $size = round(($fsize/1048576),2)." M";
  690.       } else if ($fsize >= 1024) { $size = round($fsize/1024)." K";
  691.       } else { $size = $fsize." "; }
  692.       if(!$tn_w && !$tn_h && $ext==".gif"){
  693.         $tn_w=$w;
  694.         $tn_h=$h;
  695.       }
  696.                   if($spoiler) {
  697.                   $size= "Spoiler Image, $size";
  698.                       $imgsrc = "<br><a href=\"".$displaysrc."\" target=_blank><img src=\"".SPOILER_THUMB."\" border=0 align=left hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";          
  699.                   } elseif($tn_w && $tn_h){//when there is size...
  700.         if(@is_file(THUMB_DIR.$tim.'s.jpg')){
  701.           $imgsrc = "<br><a href=\"".$displaysrc."\" target=_blank><img src=".$thumbdir.$tim.'s.jpg'." border=0 align=left width=$tn_w height=$tn_h hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";
  702.         }else{
  703.           $imgsrc = "<a href=\"".$displaysrc."\" target=_blank><span class=\"tn_thread\" title=\"".$size."B\">Thumbnail unavailable</span></a>";
  704.         }
  705.       }else{
  706.         if(@is_file(THUMB_DIR.$tim.'s.jpg')){
  707.           $imgsrc = "<br><a href=\"".$displaysrc."\" target=_blank><img src=".$thumbdir.$tim.'s.jpg'." border=0 align=left hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";
  708.         }else{
  709.           $imgsrc = "<a href=\"".$displaysrc."\" target=_blank><span class=\"tn_thread\" title=\"".$size."B\">Thumbnail unavailable</span></a>";
  710.         }
  711.       }
  712.       if (!is_file($src)) {
  713.               $dat.='<img src="'.$imgurl.'filedeleted.gif" alt="File deleted.">';
  714.       } else {
  715.         $dimensions=($ext=='.pdf')?'PDF':"{$w}x{$h}";
  716.         if ($resno) {
  717.               $dat.="<span class=\"filesize\">".S_PICNAME."<a href=\"$linksrc\" target=\"_blank\">$time$ext</a>-(".$size."B, ".$dimensions.", <span title=\"".$longname."\">".$shortname."</span>)</span>".$imgsrc;
  718.                                 } else {
  719.                       $dat.="<span class=\"filesize\">".S_PICNAME."<a href=\"$linksrc\" target=\"_blank\">$time$ext</a>-(".$size."B, ".$dimensions.")</span>".$imgsrc;
  720.         }
  721.       }
  722.     }
  723.     //  Main creation
  724.     $dat.="<a name=\"$resno\"></a>\n<input type=checkbox name=\"$no\" value=delete><span class=\"filetitle\">$sub</span> \n";
  725.     $dat.="<span class=\"postername\">$name</span> $now <span id=\"nothread$no\">";
  726.  
  727.     if($sticky==1) {
  728.         $stickyicon=' <img src="'.$imgurl.'sticky.gif" alt="sticky"> ';
  729.     } else { $stickyicon=""; }
  730.     if($closed==1) {
  731.         $stickyicon .= ' <img src="'.$imgurl.'closed.gif" alt="closed"> ';
  732.     }
  733.    
  734.     if(PARTY==1) {
  735.         $dat .= "<img src='http://img.4chan.org/xmashat.gif' style='position:absolute;margin-top:-100px;left:0px;'>";
  736.     }
  737.        
  738.     if($resno) {
  739.         $dat.="<a href=\"#$no\" class=\"quotejs\">No.</a><a href=\"javascript:quote('$no')\" class=\"quotejs\">$no</a> $stickyicon &nbsp; ";
  740.     } else {
  741.         $dat.="<a href=\"".RES_DIR.$no.PHP_EXT."#".$no."\" class=\"quotejs\">No.</a><a href=\"".RES_DIR.$no.PHP_EXT."#q".$no."\" class=\"quotejs\">$no</a> $stickyicon &nbsp; [<a href=\"".RES_DIR.$no.PHP_EXT."\">".S_REPLY."</a>]";
  742.     }
  743.     $dat.="</span>\n<blockquote>$com</blockquote>";
  744.  
  745.      // Deletion pending
  746.       if(isset($log[$no]['old'])) $dat.="<span class=\"oldpost\">".S_OLD."</span><br>\n";
  747.  
  748.     $resline = $log[$no]['children'];
  749.     ksort($resline);
  750.     $countres=count($log[$no]['children']);
  751.     $t=0;
  752.     if($sticky==1) {
  753.             $disam=1;
  754.     } elseif(defined('REPLIES_SHOWN')) {
  755.         $disam=REPLIES_SHOWN;
  756.     } else {
  757.         $disam=5;
  758.     }
  759.     $s=$countres - $disam;
  760.           $cur=1;
  761.           while ($s >= $cur) {
  762.             list($row) = each($resline);
  763.       if($log[$row]["fsize"]!=0) { $t++; }
  764.             $cur++;
  765.                 }
  766.     if ($countres!=0) reset($resline);
  767.  
  768.     if(!$resno){
  769.     if ($s<2) { $posts=" post"; } else { $posts=" posts"; }
  770.     if ($t<2) { $replies="reply"; } else { $replies="replies"; }
  771.      if(($s>0)&&($t==0)){
  772.       $dat.="<span class=\"omittedposts\">".$s.$posts." omitted. Click Reply to view.</span>\n";
  773.      } elseif (($s>0)&&($t>0)) {
  774.       $dat.="<span class=\"omittedposts\">".$s.$posts." and ".$t." image ".$replies." omitted. Click Reply to view.</span>\n";
  775.      }
  776.     }else{$s=0;}
  777.        
  778.     while(list($resrow)=each($resline)){
  779.       if($s>0){$s--;continue;}
  780.       //list($no,$sticky,$permasage,$closed,$now,$name,$email,$sub,$com,$host,$pwd,$filename,$ext,$w,$h,$tn_w,$tn_h,$tim,$time,$md5,$fsize,$root,$resto)=$resrow;
  781.       extract($log[$resrow]);
  782.       if(!$no){break;}
  783.  
  784.         //POST FILTERING
  785.         if(JANITOR_BOARD == 1) {
  786.                 $name = broomcloset_capcode($name);
  787.         }
  788.         if($email) $name = "<a href=\"mailto:$email\" class=\"linkmail\">$name</a>";
  789.     if(strpos($sub,"SPOILER<>")===0) {
  790.         $sub = substr($sub,strlen("SPOILER<>")); //trim out SPOILER<>
  791.         $spoiler = 1;
  792.     } else $spoiler = 0;
  793.     $com = auto_link($com,$resno);
  794.     if(!$resno) list($com,$abbreviated) = abbreviate($com, MAX_LINES_SHOWN);
  795.  
  796.           if(isset($abbreviated)&&$abbreviated) $com .= "<br /><span class=\"abbr\">Comment too long. Click <a href=\"".RES_DIR.($resto?$resto:$no).PHP_EXT."#$no\">here</a> to view the full text.</span>";
  797.          
  798.                 // Picture file name
  799.                 $r_img = $path.$tim.$ext;
  800.                 $r_displaysrc = $imgdir.$tim.$ext;
  801.             $r_linksrc = ((USE_SRC_CGI==1)?(str_replace(".cgi","",$imgdir).$tim.$ext):$r_displaysrc);
  802.         if(defined('INTERSTITIAL_LINK')) $r_linksrc = str_replace(INTERSTITIAL_LINK,"",$r_linksrc);
  803.                 $r_src = IMG_DIR.$tim.$ext;
  804.                 $longname = $filename.$ext;
  805.                 if (strlen($filename)>30) {
  806.                   $shortname = substr($filename, 0, 30)."(...)".$ext;
  807.                 } else {
  808.                   $shortname = $longname;
  809.                 }
  810.                 // img tag creation
  811.                 $r_imgsrc = "";
  812.                 if($ext){
  813.                         // turn the 32-byte ascii md5 into a 24-byte base64 md5
  814.                 $shortmd5 = base64_encode(pack("H*", $md5));
  815.                   if ($fsize >= 1048576) { $size = round(($fsize/1048576),2)." M";
  816.                   } else if ($fsize >= 1024) { $size = round($fsize/1024)." K";
  817.                   } else { $size = $fsize." "; }
  818.                   if(!$tn_w && !$tn_h && $ext==".gif"){
  819.                     $tn_w=$w;
  820.                     $tn_h=$h;
  821.                   }
  822.                   if($spoiler) {
  823.                   $size= "Spoiler Image, $size";
  824.                       $r_imgsrc = "<br><a href=\"".$r_displaysrc."\" target=_blank><img src=\"".SPOILER_THUMB."\" border=0 align=left hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";              
  825.                   }
  826.                   elseif($tn_w && $tn_h){//when there is size...
  827.                     if(@is_file(THUMB_DIR.$tim.'s.jpg')){
  828.                       $r_imgsrc = "<br><a href=\"".$r_displaysrc."\" target=_blank><img src=".$thumbdir.$tim.'s.jpg'." border=0 align=left width=$tn_w height=$tn_h hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";
  829.                     }else{
  830.                       $r_imgsrc = "<a href=\"".$r_displaysrc."\" target=_blank><span class=\"tn_reply\" title=\"".$size."B\">Thumbnail unavailable</span></a>";
  831.                     }
  832.                   }else{
  833.                     if(@is_file(THUMB_DIR.$tim.'s.jpg')){
  834.                       $r_imgsrc = "<br><a href=\"".$r_displaysrc."\" target=_blank><img src=".$thumbdir.$tim.'s.jpg'." border=0 align=left hspace=20 alt=\"".$size."B\" md5=\"$shortmd5\"></a>";
  835.                     }else{
  836.                       $r_imgsrc = "<a href=\"".$r_displaysrc."\" target=_blank><span class=\"tn_reply\" title=\"".$size."B\">Thumbnail unavailable</span></a>";
  837.                     }
  838.                   }
  839.                   if (!is_file($r_src)) {
  840.                     $r_imgreply='<br><img src="'.$imgurl.'filedeleted-res.gif" alt="File deleted.">';
  841.                   } else {
  842.                         $dimensions=($ext=='.pdf')?'PDF':"{$w}x{$h}";
  843.                 if ($resno) {
  844.                             $r_imgreply="<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"filesize\">".S_PICNAME."<a href=\"$r_linksrc\" target=\"_blank\">$time$ext</a>-(".$size."B, ".$dimensions.", <span title=\"".$longname."\">".$shortname."</span>)</span>".$r_imgsrc;
  845.                                                         } else {
  846.                             $r_imgreply="<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"filesize\">".S_PICNAME."<a href=\"$r_linksrc\" target=\"_blank\">$time$ext</a>-(".$size."B, ".$dimensions.")</span>".$r_imgsrc;
  847.               }
  848.                   }
  849.                 }
  850.                
  851.       // Main Reply creation
  852.       $dat.="<a name=\"$no\"></a>\n";
  853.                 $dat.="<table><tr><td nowrap class=\"doubledash\">&gt;&gt;</td><td id=\"$no\" class=\"reply\">\n";
  854. //      if (($t>3)&&($fsize!=0)) {
  855. //      $dat.="&nbsp;&nbsp;&nbsp;<b>Image hidden</b>&nbsp;&nbsp; $now No.$no \n";
  856. //                      } else {
  857.       $dat.="<input type=checkbox name=\"$no\" value=delete><span class=\"replytitle\">$sub</span> \n";
  858.       $dat.="<span class=\"commentpostername\">$name</span> $now <span id=\"norep$no\">";
  859.       if($resno) {
  860.         $dat.="<a href=\"#$no\" class=\"quotejs\">No.</a><a href=\"javascript:quote('$no')\" class=\"quotejs\">$no</a></span>";
  861.       } else {
  862.         $dat.="<a href=\"".RES_DIR.$resto.PHP_EXT."#$no\" class=\"quotejs\">No.</a><a href=\"".RES_DIR.$resto.PHP_EXT."#q$no\" class=\"quotejs\">$no</a></span>";
  863.       }
  864.       if(isset($r_imgreply)) $dat.=$r_imgreply;
  865.       $dat.="<blockquote>$com</blockquote>";
  866. //      }
  867.       $dat.="</td></tr></table>\n";
  868.         unset($r_imgreply);
  869.     }
  870.     $dat.="<br clear=left><hr>\n";
  871.     clearstatcache();//clear stat cache of a file
  872.     //mysql_free_result($resline);
  873.         $p++;
  874.     if($resno){break;} //only one tree line at time of res
  875.   }
  876.         // bottom of a page
  877.         if(BOTTOM_AD == 1) {
  878.                 $bottomad = "";
  879.                
  880.                 if (defined("BOTTOM_TXT") && BOTTOM_TXT) {
  881.                         $bottomad .= ad_text_for(BOTTOM_TXT);
  882.                 }
  883.                
  884.                 if (defined("BOTTOM_TABLE") && BOTTOM_TABLE) {
  885.                         list($bottomimg,$bottomlink) = rid(BOTTOM_TABLE,1);
  886.                         $bottomad .= "<center><a href=\"$bottomlink\" target=\"_blank\"><img style=\"border:1px solid black;\" src=\"$bottomimg\" width=728 height=90 border=0 /></a></center>";
  887.                 }
  888.                
  889.                 if($bottomad)
  890.                         $dat .= "$bottomad<hr>";
  891.         }
  892.                
  893. $dat.='<table align=right><tr><td nowrap align=center class=deletebuttons>
  894. <input type=hidden name=mode value=usrdel>'.S_REPDEL.' [<input class=checkbox type=checkbox name=onlyimgdel value=on>'.S_DELPICONLY.']<br>
  895. '.S_DELKEY.' <input class=inputtext type=password name="pwd" size=8 maxlength=8 value="">
  896. <input type=submit value="'.S_DELETE.'"><input type="button" value="Report" onclick="var o=document.getElementsByTagName(\'INPUT\');for(var i=0;i<o.length;i++)if(o[i].type==\'checkbox\' && o[i].checked && o[i].value==\'delete\') return reppop(\''.PHP_SELF_ABS.'?mode=report&no=\'+o[i].name+\'\');"></form><script>document.delform.pwd.value=get_pass("4chan_pass");</script></td></tr>';
  897. if (strpos($_SERVER['SERVER_NAME'],".4chan.org")) {
  898.         $dat.='<tr><td align="right">Style [';
  899.         $dat.='<a href="#" onclick="setActiveStyleSheet(\'Yotsuba\'); return false;">Yotsuba</a> | ';
  900.         $dat.='<a href="#" onclick="setActiveStyleSheet(\'Yotsuba B\'); return false;">Yotsuba B</a> | ';
  901.         $dat.='<a href="#" onclick="setActiveStyleSheet(\'Futaba\'); return false;">Futaba</a> | ';
  902.         $dat.='<a href="#" onclick="setActiveStyleSheet(\'Burichan\'); return false;">Burichan</a>]</td></tr>';
  903. }
  904. $dat.='</table>';
  905.  
  906.     if(!$resno){ // if not in res display mode
  907.       $prev = $st - PAGE_DEF;
  908.       $next = $st + PAGE_DEF;
  909.     // Page navigation
  910.       $dat.="<table class=pages align=left border=1><tr>";
  911.       if($prev >= 0){ //ok to make prev button
  912.         if($prev==0){
  913.           $dat.="<form action=\"".PHP_SELF2."\" onsubmit='location=this.action;return false;' method=get><td>";
  914.         }else{
  915.           $dat.="<form action=\"".$prev/PAGE_DEF.PHP_EXT."\" onsubmit='location=this.action;return false;' method=get><td>";
  916.         }
  917.         $dat.="<input type=submit value=\"".S_PREV."\" accesskey=\"z\">";
  918.         $dat.="</td></form>";
  919.       }else{$dat.="<td>".S_FIRSTPG."</td>";}
  920.                 // page listing
  921.       $dat.="<td>";
  922.       for($i = 0; $i < $counttree ; $i+=PAGE_DEF){
  923.         if( !(PAGE_MAX > 0) )
  924.                 if($i&&!($i%(PAGE_DEF*10))){$dat.="<br>";} // linebreak every 10 pages
  925.         if($st==$i){$dat.="[<b>".($i/PAGE_DEF)."</b>] ";} // don't link current page
  926.         else{
  927.           if($i==0){$dat.="[<a href=\"".PHP_SELF2."\">0</a>] ";}
  928.           else{$dat.="[<a href=\"".($i/PAGE_DEF).PHP_EXT."\">".($i/PAGE_DEF)."</a>] ";}
  929.         }
  930.       }
  931.       // continue printing up to PAGE_MAX if we're using that mode... this should rarely happen
  932.       for(; (PAGE_MAX > 0) && $i < PAGE_MAX*PAGE_DEF; $i+=PAGE_DEF) {
  933.         $dat.="[".($i/PAGE_DEF)."] ";
  934.       }
  935.      
  936.       $dat.="</td>";
  937.  
  938.       if($p >= PAGE_DEF && $counttree > $next){ // ok to make next button
  939.         $dat.="<form action=\"".$next/PAGE_DEF.PHP_EXT."\" onsubmit='location=this.action;return false' method=get><td>";
  940.         $dat.="<input type=submit value=\"".S_NEXT."\" accesskey=\"x\">";
  941.         $dat.="</td></form>";
  942.       }else{$dat.="<td>".S_LASTPG."</td>";}
  943.         $dat.="</tr></table><br clear=all>\n";
  944.     }
  945.     foot($dat);
  946.     //if($resno){echo $dat;break;}
  947.     if($resno) {
  948.         logtime("Printing thread $resno page");
  949.             $logfilename=RES_DIR.$resno.PHP_EXT;
  950.             print_page($logfilename, $dat);
  951.                 $dat='';
  952.       if(!$rebuild) $deferred = updatelog(0);
  953.       break;
  954.     }
  955.     logtime("Printing index page");
  956.     if($page==0){$logfilename=PHP_SELF2;}
  957.     else{$logfilename=$page/PAGE_DEF.PHP_EXT;}
  958.     print_page($logfilename, $dat);
  959.     if(!$resno && $page==0 && USE_RSS==1) {
  960.         include_once '/www/global/rss.php';
  961.         rss_dump();
  962.     }
  963.     if(UPDATE_THROTTLING >= 1) {
  964.                 clearstatcache();
  965.                 if(@filemtime("updatelog.stamp") == $update_start)
  966.                         unlink("updatelog.stamp");
  967.     }
  968.     //chmod($logfilename,0666);
  969.   }
  970.   //mysql_free_result($treeline);
  971.   if(isset($deferred)) return $deferred;
  972.   return false;
  973. }
  974.  
  975. /* head */
  976. function head(&$dat,$res,$error=0){
  977.         $titlepart = '';
  978.         if(JANITOR_BOARD == 1) {
  979.                 $dat .= broomcloset_head($dat);
  980.         }
  981.  
  982.   if (SHOWTITLEIMG == 1) {
  983.                 //$titleimg = rid('title_banners');
  984.           $titleimg = rid_in_directory("/dontblockthis/title/");
  985.           $titlepart.= '<img width=300 height=100 src="'.$titleimg.'">';
  986.         } else if (SHOWTITLEIMG == 2) {
  987.           $titlepart.= '<img width=300 height=100 src="'.TITLEIMG.'" onclick="this.src=this.src;">';
  988.         }
  989.   $include1=file_get_contents_cached(NAV_TXT);
  990.   $cookiejs="function get_cookie(name){with(document.cookie){var index=indexOf(name+\"=\");if(index==-1) return '';index=indexOf(\"=\",index)+1;var endstr=indexOf(\";\",index);if(endstr==-1) endstr=length;return decodeURIComponent(substring(index,endstr));}};\nfunction get_pass(name){var pass=get_cookie(name);if(pass) return pass;var chars=\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";var pass='';for(var i=0;i<8;i++){var rnd=Math.floor(Math.random()*chars.length);pass+=chars.substring(rnd,rnd+1);}return(pass);}\n";
  991.   $cookiejs .= 'function toggle(name){var a=document.getElementById(name); a.style.display = ((a.style.display!="block")?"block":"none");}';
  992.   $scriptjs = '';
  993.   // set styleswitcher script configuration variables
  994.   if(DEFAULT_BURICHAN==1) {
  995.         $scriptjs .= '<script type="text/javascript">var style_group="ws_style";</script>';
  996.   } else {
  997.         $scriptjs .= '<script type="text/javascript">var style_group="nws_style";</script>';
  998.   }
  999.         $scriptjs .='<script type="text/javascript" src="'.DATA_SERVER.'script.js"></script>';
  1000.   $dat.='<html><head>
  1001. <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
  1002. <meta name="robots" content="'.META_ROBOTS.'"/>
  1003. <meta name="description" content="'.META_DESCRIPTION.'"/>
  1004. <meta name="keywords" content="'.META_KEYWORDS.'"/>';
  1005.         if (RTA==1) {
  1006.                 $dat .= "\n<meta name=\"RATING\" content=\"RTA-5042-1996-1400-1577-RTA\" />";
  1007.         }
  1008. $styles = array(
  1009.         'Yotsuba' => 'yotsuba.8.css',
  1010.         'Yotsuba B' => 'yotsublue.8.css',
  1011.         'Futaba' => 'futaba.8.css',
  1012.         'Burichan' => 'burichan.8.css',
  1013. );
  1014.         if (DEFAULT_BURICHAN==1) {
  1015.                 foreach($styles as $style=>$stylecss) {
  1016.                         $rel = ( ($style == 'Yotsuba B') ? 'stylesheet' : 'alternate stylesheet' );
  1017.                         $dat .= "<link rel=\"$rel\" type=\"text/css\" href=\"".DATA_SERVER."$stylecss\" title=\"$style\">";
  1018.                 }
  1019.         } else {
  1020.                 if(defined('CSS_FORCE')) {
  1021.                         foreach($styles as $style=>$stylecss) {
  1022.                                 $rel = ( ($style == 'Yotsuba') ? 'stylesheet' : 'alternate stylesheet' );
  1023.                                 $dat .= "<link rel=\"$rel\" type=\"text/css\" href=\"".CSS_FORCE."\" title=\"$style\">";
  1024.                         }
  1025.                 }
  1026.                 else {
  1027.                         foreach($styles as $style=>$stylecss) {
  1028.                                 $rel = ( ($style == 'Yotsuba') ? 'stylesheet' : 'alternate stylesheet' );
  1029.                                 $dat .= "<link rel=\"$rel\" type=\"text/css\" href=\"".DATA_SERVER."$stylecss\" title=\"$style\">";
  1030.                         }
  1031.                 }
  1032.         }
  1033.  
  1034. if(USE_RSS==1)
  1035.         $dat .= '<link rel="alternate" title="RSS feed" href="/'.BOARD_DIR.'/index.rss" type="application/rss+xml" />';
  1036. $dat.='<title>'.strip_tags(TITLE).'</title>
  1037. <script type="text/javascript"><!--
  1038. '.$cookiejs.'
  1039. //--></script>
  1040. '.$scriptjs;
  1041.  
  1042. if (FIXED_TEXT_AD == 1 && file_exists(FIXED_TEXT_PATH)) {
  1043.         $dat.="<style>.postarea { padding-left:400px; }</style>";
  1044. }
  1045.  
  1046. $dat .= '</head>
  1047. <body bgcolor="#FFFFEE" text="#800000" link="#0000EE" vlink="#0000EE">'.$include1;
  1048.  
  1049. $dat.='<div class="logo">
  1050. '.$titlepart.'<br>
  1051. <font size=5>
  1052. <b><SPAN>'.TITLE.'</SPAN></b></font>';
  1053. if(defined('SUBTITLE'))
  1054.         $dat .= '<br><font size=1>'.SUBTITLE.'</font>';
  1055. $dat.='</div>
  1056. <hr width="90%" size=1>
  1057. ';
  1058. if(LEADERBOARD_AD == 1) {
  1059.                 if(defined('LEADERBOARD_TXT') && LEADERBOARD_TXT) {
  1060.                         $dat.='<div style="text-align: center">' .
  1061.                                 ad_text_for(LEADERBOARD_TXT) .
  1062.                         '</div><hr>';
  1063.                 }
  1064.                 else if(defined('LEADERBOARD_TABLE')) {
  1065.                         list($ldimg,$ldhref) = rid(LEADERBOARD_TABLE,1);
  1066.                         $dat.='<div style="text-align: center"><a href="'.$ldhref.'" target="_blank"><img src="'.$ldimg.'" border="0"></a></div><hr>';
  1067.                 }
  1068.                 else
  1069.                         $dat.='<div style="text-align: center"><a href="'.LEADERBOARD_LINK.'" target="_blank"><img src="http://content.4chan.org/dontblockthis/'.LEADERBOARD_IMG.'" border="0"></a></div><hr>';
  1070. }
  1071. }
  1072.  
  1073. /* Contribution form */
  1074. function form(&$dat,$resno,$admin=""){
  1075.   global $log; log_cache();
  1076.   $maxbyte = MAX_KB * 1024;
  1077.   $no=$resno;
  1078.   $closed=0;
  1079.   $msg='';
  1080.   $hidden='';
  1081.   if($resno){
  1082.     $closed = $log[$resno]['closed'];
  1083.  
  1084.     $msg.="[<a href=\"../".PHP_SELF2."\" accesskey=\"a\">".S_RETURN."</a>]\n";
  1085.     $msg.="<table width='100%'><tr><th bgcolor=#e04000>\n";
  1086.     $msg.="<font color=#FFFFFF>".S_POSTING."</font>\n";
  1087.     $msg.="</th></tr></table>\n";
  1088.   }
  1089.   if($admin){
  1090.     $hidden = "<input type=hidden name=admin value=\"".ADMIN_PASS."\">";
  1091.     $msg = "<h4>".S_NOTAGS."</h4>";
  1092.   }
  1093. if($closed!=1) {
  1094.   $dat.=$msg;
  1095.   //form_ads($dat);
  1096. if(OEKAKI_BOARD == 1) {
  1097.         require_once 'oekaki.php';
  1098.         if($_GET['mode'] != 'oe_finish')
  1099.                 oe_form($dat,$resno);
  1100.         else
  1101.                 oe_preview($dat);              
  1102. }
  1103.   $dat.='<div align="center" class="postarea"><form name="post" action="';
  1104.         $dat.=PHP_SELF_ABS.'" method="POST" enctype="multipart/form-data">
  1105. '.$hidden.'<input type=hidden name="MAX_FILE_SIZE" value="'.$maxbyte.'">
  1106. ';
  1107. if($no){$dat.='<input type=hidden name=resto value="'.$no.'">
  1108. ';}
  1109.         if((FIXED_TEXT_AD == 1) && $fixedad = ad_text_for(FIXED_TEXT_PATH)) {
  1110.         $dat.='<div id="ad">'.$fixedad.'</div>';
  1111.         }
  1112. if(FORCED_ANON == 1) {
  1113.         $dat.='<table cellpadding=1 cellspacing=1><tr colspan=2><td><input type=hidden name=name><input type=hidden name=sub>&nbsp;</td></tr>'
  1114.         .'<tr><td></td><td class="postblock" align="left"><b>'.S_EMAIL.'</b></td><td><input class=inputtext type=text name=email size="28"><span id="tdname"></span><span id="tdemail"></span>';
  1115. } else {
  1116. $dat.='<table cellpadding=1 cellspacing=1>
  1117. <tr><td></td><td class="postblock" align="left"><b>'.S_NAME.'</b></td><td><input class=inputtext type=text name=name size="28"><span id="tdname"></span></td></tr>
  1118. <tr><td></td><td class="postblock" align="left"><b>'.S_EMAIL.'</b></td><td><input class=inputtext type=text name=email size="28"><span id="tdemail"></span></td></tr>
  1119. <tr><td></td><td class="postblock" align="left"><b>'.S_SUBJECT.'</b></td><td><input class=inputtext type=text name=sub size="35">';
  1120. }
  1121. if($admin){
  1122. $dat.='<tr><td></td><td class="postblock" align="left"><b>Reply ID</b></td><td><input class=inputtext type=text name=resto size="10"> [<label><input type=checkbox name=age value=1>Age</label>] ';
  1123. }
  1124. $dat.='<input type=submit value="'.S_SUBMIT.'" accesskey="s">';
  1125. if (SPOILERS==1) {
  1126.   $dat.=' [<label><input type=checkbox name=spoiler value=on>'.S_SPOILERS.'</label>]';
  1127. };
  1128. $dat.='</td></tr>
  1129. <tr><td valign=bottom></td><td class="postblock" align="left"><b>'.S_COMMENT.'</b></td><td><textarea class=inputtext name=com cols="48" rows="4" wrap=soft></textarea></td></tr>
  1130. ';
  1131. if(OEKAKI_BOARD == 1 && $_GET['mode'] == 'oe_finish') { require_once 'oekaki.php'; oe_finish_form($dat); }
  1132. elseif (MAX_IMGRES!=0) {
  1133.         $dat.='<tr><td></td><td class="postblock" align="left"><b>'.S_UPLOADFILE.'</b></td>
  1134.         <td><input type=file name=upfile size="35">';
  1135.         if (!$resno&&NO_TEXTONLY!=1) {
  1136.         $dat.='[<label><input type=checkbox name=textonly value=on>'.S_NOFILE.'</label>]';
  1137.         }
  1138.         $dat.='</td></tr>';
  1139. }
  1140. $dat.='<tr><td></td><td class="postblock" align="left"><b>'.S_DELPASS.'</b></td><td><input class=inputtext type=password name="pwd" size=8 maxlength=8 value=""><small>'.S_DELEXPL.'</small><input type=hidden name=mode value="regist"></td></tr>
  1141. <tr><td></td><td colspan=2>
  1142. <table border=0 cellpadding=0 cellspacing=0 width="100%"><tr><td class="rules">'.S_RULES;
  1143. if(!$resno && SHOW_UNIQUES == 1) {
  1144.   $dat.='<LI>Currently <b>'.$GLOBALS['ipcount'].'</b> unique user posts.';
  1145. }
  1146. $dat.='</td><td align="right" valign="center">'.DONATE.'</td></tr>';
  1147. if(FORCED_ANON==1) { // extra spacer to make up for the 2 missing table rows
  1148.         $dat .='<tr><td>&nbsp;</td></tr>';
  1149. }
  1150. if(SHOW_BLOTTER == 1) {
  1151. list($blotdate,$blotcontents) = blotter_contents();
  1152. $dat.='<tr><td class="rules">
  1153. <script type="text/javascript"><!--
  1154. function updateBlotterVisible() {
  1155.         if(get_cookie("blotter_hide") == "show") {
  1156.                 document.getElementById("blotter").style.display = \'inline\';
  1157.         } else {
  1158.                 document.getElementById("blotter").style.display = \'none\';
  1159.         }
  1160. }
  1161.  
  1162. function toggleBlotter() {
  1163.         if(get_cookie("blotter_hide") == "show") {
  1164.                 document.cookie = "blotter_hide=hide; expires=Thu, 4 Feb 2044 04:04:04 UTC; domain=4chan.org; path=/";
  1165.         } else {
  1166.                 document.cookie = "blotter_hide=show; expires=Thu, 4 Feb 2044 04:04:04 UTC; domain=4chan.org; path=/";
  1167.         }
  1168.         updateBlotterVisible();
  1169. }
  1170. document.write(\'<div style="position:relative;"><div style="top:0px;left:0px;position:absolute;" class="rules">'.$blotdate.'</div><div style="top:0px;right:0px;position:absolute;"><a href="javascript:void(0)" onclick="toggleBlotter()">Show/Hide</a> <a href="'.BLOTTER_URL.'?all">Show All</a></div><div id="blotter" style="display:none" class="rules"><br/>\');
  1171.         document.write(' . $blotcontents . ');
  1172. document.write(\'</div></div>\');
  1173. updateBlotterVisible();
  1174. -->
  1175. </script>
  1176. </td></tr>';
  1177. }
  1178. $dat.='</table></td></tr></table></form></div><hr>
  1179. <script>with(document.post) {name.value=get_cookie("4chan_name"); email.value=get_cookie("4chan_email"); pwd.value=get_pass("4chan_pass"); }</script>
  1180. ';
  1181. } else { // closed thread
  1182.         $dat.="[<a href=\"../".PHP_SELF2."\" accesskey=\"a\">".S_RETURN."</a>]<hr>\n";
  1183.         form_ads($dat);
  1184.         $dat.='<table style="text-align:center;width:100%;height:300px;"><tr valign="middle"><td align="center"><font color=red size=5 style=""><b>Thread closed.<br/>You may not reply at this time.</b></font></tr></td></table>';
  1185. }
  1186.         if (BANROT_AD==1) {
  1187.             /*if(!$banadquery=mysql_global_call("select url,img from ".BANROTLOG." order by rand() limit 1")){echo S_SQLFAIL;}
  1188.             $banadrow=mysql_fetch_row($banadquery);
  1189.             list($ba_url,$ba_img)=$banadrow;*/
  1190.             $dat.='<center>';
  1191.                 if(defined('TOPAD_TABLE')) {
  1192.                         list($topad, $toplink) = rid(TOPAD_TABLE, 1);
  1193.                         $dat .= "<a href=\"$toplink\" target=\"_blank\"><img style=\"border:1px solid black;\" src=\"$topad\" width=468 height=60 border=0 /></a>";
  1194.                 }
  1195.                 else {
  1196.                         $dat .= rotating_ad_banner();
  1197.                 }
  1198.             /*
  1199.             $dat.='<a href="http://webhosting.cologuys.com" target="_blank"><img src="http://content.4chan.org/dontblockthis/CG_100x60_2.gif" border="0"></a>';
  1200.             if ($ba_url != "") {
  1201.                     $dat.='<a href="'.BANROT_PHP.'?url='.$ba_url.'" target="_blank"><img src="'.$ba_img.'" border="0"></a>';
  1202.             } else {
  1203.                     $dat.='<img src="'.$ba_img.'" border="0">';
  1204.             }*/
  1205.  
  1206.         }
  1207.        
  1208.         if(BANROT2_AD==1) {
  1209.         /*      $dat .= @file_get_contents('/www/global/topad.txt');
  1210.             $dat.='<a href="http://webhosting.cologuys.com" target="_blank"><img src="http://content.4chan.org/dontblockthis/CG_100x60_2.gif" border="0"></a>';
  1211.             $dat.="</center><hr>\n";*/
  1212.         }
  1213.         elseif (BANROT_B==1) {
  1214.                 /*if(!$banadquery=mysql_global_call("select url,img from ".BANROT_B_LOG." where DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= installed) ORDER BY RAND() limit 1")){echo S_SQLFAIL;}
  1215.                 $banadrow=mysql_fetch_row($banadquery);
  1216.                 list($ba_url,$ba_img)=$banadrow;
  1217.                 $dat.='<br/>';
  1218.                 if ($ba_url != "") {
  1219.                         $dat.='<a href="'.$ba_url.'" target="_blank"><img src="'.$ba_img.'" border="0"></a>';
  1220.                 } else {
  1221.                         $dat.='<img src="'.$ba_img.'" border="0">';
  1222.                 }
  1223.           $dat.="<br><a href=\"http://www.4chan.org/advertise/\" target=\"_blank\"><small>Buy a banner for this board!</small></a></center><hr>\n";*/
  1224.         }
  1225.         elseif(NOT4CHAN!=1 && BANROT_AD==1 || BANROT2_AD==1) {
  1226.         //$dat.="<br><a href=\"http://www.4chan.org/advertise/\" target=\"_blank\"><small>Advertise with 4chan!</small></a></center><hr>\n";
  1227.         $dat.="</center><hr>\n";
  1228.   }
  1229.  
  1230.   if (defined('GLOBAL_MSG') && GLOBAL_MSG!='') {
  1231.           $dat.=GLOBAL_MSG."\n<hr>\n";
  1232.   }
  1233.  
  1234.   if(JANITOR_BOARD == 1) {
  1235.         $dat = broomcloset_form($dat);
  1236.   }
  1237. }
  1238.  
  1239. function delete_uploaded_files()
  1240. {
  1241.         global $upfile_name,$path,$upfile,$dest;
  1242.         if($dest||$upfile) {
  1243.           @unlink($dest);
  1244.           @unlink($upfile);
  1245.           if(OEKAKI_BOARD == 1) { @unlink("$dest.pch"); }
  1246.         }
  1247. }
  1248.  
  1249. /* Footer */
  1250. function foot(&$dat){
  1251.  global $update_avg_secs;
  1252.  $include2=file_get_contents_cached(NAV2_TXT);
  1253. /* $dat.='<div class="footer">'.S_FOOT.'</div>
  1254. '.$include2.'
  1255. </body></html>';*/
  1256.   $dat .="$include2";
  1257.   if ($update_avg_secs) $dat .= "<!-- $update_avg_secs s -->";
  1258.   $dat .= "</body></html>";
  1259. }
  1260. function error($mes,$unused=''){
  1261.   delete_uploaded_files();
  1262.   head($dat,0,1);
  1263.   form_ads($dat);
  1264.  
  1265.   //echo "<br><br><hr size=1><br><br>\n<center><font color=red size=5><b>$mes<br><br><a href=";
  1266.   $dat .= '<table style="text-align:center;width:100%;height:300px;"><tr valign="middle"><td align="center"><font color=red size=5 style=""><b>' . $mes . '<br><br><a href=';
  1267.   if(strpos($_SERVER['REQUEST_URI'],RES_DIR)) $dat .= "../";
  1268.   //echo PHP_SELF2.">".S_RELOAD."</a></b></font></center><br><br><hr size=1>";
  1269.   $dat .=  PHP_SELF2.">".S_RELOAD."</a></b></font></tr></td></table><br><br><hr size=1>";
  1270.   if(BANROT_AD == 1 && !defined('TOPAD_TABLE')) {
  1271.             $dat.='<center>';
  1272.                 $dat .= rotating_ad_banner();
  1273.                 if(BOTTOM_AD == 1) {
  1274.                         $dat .= "<hr size=1>";
  1275.                 }
  1276.   }
  1277.  if(BOTTOM_AD == 1) {
  1278.         $bottomad = ad_text_for(BOTTOMAD);
  1279.         if($bottomad)
  1280.                 $dat .= "$bottomad<hr>";
  1281.   }
  1282.   $dat .= "</center>";
  1283.   foot($dat);
  1284.   die($dat);
  1285. }
  1286.  
  1287. /* Auto Linker */
  1288. function normalize_link_cb($m) {
  1289.         $subdomain = $m[1];
  1290.         $original = $m[0];
  1291.         $board = strtolower($m[2]);
  1292.         $m[0] = $m[1] = $m[2] = '';
  1293.         for($i=count($m)-1;$i>2;$i--) {
  1294.                 if($m[$i]) { $no = $m[$i]; break; }
  1295.         }
  1296.         if($subdomain == 'www' || $subdomain == 'static' || $subdomain == 'content')
  1297.                 return $original;
  1298.         if($board == BOARD_DIR)
  1299.                 return "&gt;&gt;$no";
  1300.         else
  1301.                 return "&gt;&gt;&gt;/$board/$no";
  1302. }
  1303. function normalize_links($proto) {
  1304.         // change http://xxx.4chan.org/board/res/no links into plaintext >># or >>>/board/#
  1305.         if(strpos($proto,"4chan.org")===FALSE) return $proto;
  1306.        
  1307.         $proto = preg_replace_callback('@http://([A-za-z]*)[.]4chan[.]org/(\w+)/(?:res/(\d+)[.]html(?:#q?(\d+))?|\w+.php[?]res=(\d+)(?:#(\d+))?|)(?=[\s.<!?,]|$)@i','normalize_link_cb',$proto);
  1308.         // rs.4chan.org to >>>rs/query+string
  1309.         $proto = preg_replace('@http://rs[.]4chan[.]org/\?s=([a-zA-Z0-9$_.+-]+)@i','&gt;&gt;&gt;/rs/$1',$proto);
  1310.         return $proto;
  1311. }
  1312.  
  1313. function intraboard_link_cb($m) {
  1314.         global $intraboard_cb_resno, $log;
  1315.         $no = $m[1];
  1316.         $resno = $intraboard_cb_resno;
  1317.         if(isset($log[$no])) {
  1318.                 $resto = $log[$no]['resto'];
  1319.                 $resdir = ($resno ? '' : RES_DIR);
  1320.                 $ext = PHP_EXT;
  1321.                 if($resno && $resno==$resto) // linking to a reply in the same thread
  1322.                         return "<a href=\"#$no\" class=\"quotelink\" onClick=\"replyhl('$no');\">&gt;&gt;$no</a>";
  1323.                 elseif($resto==0) // linking to a thread
  1324.                         return "<a href=\"$resdir$no$ext#$no\" class=\"quotelink\">&gt;&gt;$no</a>";
  1325.                 else // linking to a reply in another thread
  1326.                         return "<a href=\"$resdir$resto$ext#$no\" class=\"quotelink\">&gt;&gt;$no</a>";
  1327.         }
  1328.         return $m[0];
  1329. }
  1330. function intraboard_links($proto, $resno) {
  1331.         global $intraboard_cb_resno;
  1332.  
  1333.         $intraboard_cb_resno = $resno;
  1334.  
  1335.         $proto = preg_replace_callback('/&gt;&gt;([0-9]+)/', 'intraboard_link_cb', $proto);
  1336.         return $proto;
  1337. }
  1338.  
  1339. function interboard_link_cb($m) {
  1340.         // on one hand, we can link to imgboard.php, using any old subdomain,
  1341.         // and let apache & imgboard.php handle it when they click on the link
  1342.         // on the other hand, we can use the database to fetch the proper subdomain
  1343.         // and even the resto to construct a proper link to the html file (and whether it exists or not)
  1344.        
  1345.         // for now, we'll assume there's more interboard links posted than interboard links visited.
  1346.         $url = DATA_SERVER . $m[1] . '/' . PHP_SELF . ($m[2] ? ('?res=' . $m[2]) : "");
  1347.         return "<a href=\"$url\" class=\"quotelink\">{$m[0]}</a>";     
  1348. }
  1349. function interboard_rs_link_cb($m) {
  1350.         // $m[1] might be a url-encoded query string, or might be manual-typed text
  1351.         // so we'll normalize it to raw text first and then re-encode it
  1352.         $lsearchquery = urlencode( urldecode($m[1]) );
  1353.         return "<a href=\"http://rs.4chan.org/?s=$lsearchquery\" class=\"quotelink\">{$m[0]}</a>";
  1354. }
  1355.  
  1356. function interboard_dis_link_cb($m) {
  1357.         $durl = $m[1]; //i don't think this is useful but just in case
  1358.         return "<a href=\"http://dis.4chan.org/read/$durl\" class=\"quotelink\">{$m[0]}</a>";
  1359. }
  1360.  
  1361. function dis_matching_re() {
  1362.         global $dis_matching_re;
  1363.        
  1364.         if (!$dis_matching_re) {
  1365.                 $boards = file('/www/global/disboards.txt');
  1366.                 foreach ($boards as $board) {
  1367.                         list($bn,) = explode("<>", $board);
  1368.                         $dis_matching_re .= $bn;
  1369.                         $dis_matching_re .= '|';
  1370.                 }
  1371.                
  1372.                 $dis_matching_re = substr($dis_matching_re, 0, -1); //lose last |
  1373.         }
  1374.        
  1375.         return $dis_matching_re;
  1376. }
  1377.  
  1378. function interboard_links($proto) {
  1379.         $boards = "an?|cm?|fa|fit|gif|h[cr]?|[bdefgkmnoprstuvxy]|wg?|ic?|y|cgl|c[ko]|mu|po|t[gv]|toy|trv|jp|r9k|sp";
  1380.         $disboards = dis_matching_re();
  1381.         $proto = preg_replace_callback('@&gt;&gt;&gt;/('.$boards.')/([0-9]*)@i', 'interboard_link_cb', $proto);
  1382.         $proto = preg_replace_callback('@&gt;&gt;&gt;/rs/([^\s<>]+)@', 'interboard_rs_link_cb', $proto);
  1383.         $proto = preg_replace_callback('@&gt;&gt;&gt;/(('.$disboards.')/[^\s<>]*)@i', 'interboard_dis_link_cb', $proto);
  1384.         return $proto;
  1385. }
  1386.  
  1387. function auto_link($proto,$resno){
  1388.         $proto = normalize_links($proto);
  1389.                
  1390.         // auto-link remaining 4chan.org URLs if they're not part of HTML
  1391.         if(strpos($proto,"4chan.org")!==FALSE) {
  1392.                 $proto = preg_replace('/(http:\/\/(?:[A-Za-z]*\.)?)(4chan)(\.org)(\/)([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i',"<a href=\"\\0\" target=\"_blank\">\\0</a>",$proto);
  1393.                 $proto = preg_replace('/([<][^>]*?)<a href="((http:\/\/(?:[A-Za-z]*\.)?)(4chan)(\.org)(\/)([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?)" target="_blank">\\2<\/a>([^<]*?[>])/i', '\\1\\3\\4\\5\\6\\7\\8', $proto);
  1394.         }
  1395.        
  1396.         $proto = intraboard_links($proto,$resno);
  1397.         $proto = interboard_links($proto);
  1398.         return $proto;
  1399. }
  1400.  
  1401. function auto_ban_poster($nametrip, $banlength, $global, $reason, $pubreason='') {
  1402.         if(!$nametrip) $nametrip = S_ANONAME;
  1403.         if(strpos($nametrip, '</span> <span class="postertrip">!') !== FALSE) {
  1404.                 $nameparts=explode('</span> <span class="postertrip">!',$name);
  1405.                 $nametrip = "{$nameparts[0]} #{$nameparts[1]}";
  1406.         }
  1407.         $host = $_SERVER['REMOTE_ADDR'];
  1408.         $reverse = mysql_real_escape_string(gethostbyaddr($host));
  1409.         $xff = mysql_real_escape_string(getenv("HTTP_X_FORWARDED_FOR"));
  1410.        
  1411.         $nametrip = mysql_real_escape_string($nametrip);
  1412.         $global = ($global?1:0);
  1413.         $board = BOARD_DIR;
  1414.         $reason = mysql_real_escape_string($reason);
  1415.         $pubreason = mysql_real_escape_string($pubreason);
  1416.         if($pubreason) {
  1417.                 $pubreason .= "<>";
  1418.         }
  1419.  
  1420.         //if they're already banned on this board, don't insert again
  1421.         //since this is just a spam post
  1422.         //i don't think it matters if the active ban is global=0 and this one is global=1
  1423.         {
  1424.                 $existingq = mysql_global_do("select count(*)>0 from ".SQLLOGBAN." where host='$host' and active=1 and (board='$board' or global=1)");
  1425.                 $existingban = mysql_result($existingq, 0, 0);
  1426.                 if ($existingban > 0) {
  1427.                         delete_uploaded_files();
  1428.                         die();
  1429.                 }
  1430.         }
  1431.  
  1432.         if($banlength == 0) { // warning
  1433.                 // check for recent warnings to punish spammers
  1434.                 $autowarnq=mysql_global_call("SELECT COUNT(*) FROM ".SQLLOGBAN." WHERE host='$host' AND admin='Auto-ban' AND now > DATE_SUB(NOW(),INTERVAL 3 DAY) AND reason like '%$reason'");
  1435.                 $autowarncount=mysql_result($autowarnq,0,0);
  1436.                 if($autowarncount > 3) {
  1437.                         $banlength = 14;
  1438.                 }
  1439.         }
  1440.        
  1441.        
  1442.         if($banlength == -1) // permanent
  1443.                 $length = '0000' . '00' .'00'; // YYYY/MM/DD
  1444.         else {
  1445.                 $banlength = (int)$banlength;
  1446.                 if($banlength < 0) $banlength = 0;
  1447.                 $length = date("Ymd",time()+$banlength*(24*60*60));
  1448.         }
  1449.         $length .= "00"."00"."00"; // H:M:S
  1450.        
  1451.         if(!$result=mysql_global_do("INSERT INTO ".SQLLOGBAN." (board,global,name,host,reason,length,admin,reverse,xff) VALUES('$board','$global','$nametrip','$host','$pubreason<b>Auto-ban</b>: $reason','$length','Auto-ban','$reverse','$xff')")){echo S_SQLFAIL;}
  1452.         @mysql_free_result($result);
  1453.         append_ban($global ? "global" : $global, $host);
  1454. }
  1455.  
  1456. function check_blacklist($post, $dest) {
  1457.         $board = BOARD_DIR;
  1458.         $querystr = "SELECT SQL_NO_CACHE * FROM blacklist WHERE active=1 AND (boardrestrict='' or boardrestrict='$board') AND (0 ";
  1459.         foreach($post as $field=>$contents) {
  1460.                 if($contents) {
  1461.                         $contents = mysql_real_escape_string(html_entity_decode($contents));
  1462.                         $querystr .= "OR (field='$field' AND contents='$contents') ";
  1463.                 }
  1464.         }
  1465.         $querystr .= ") LIMIT 1";
  1466.         $query = mysql_global_call($querystr);
  1467.         if(mysql_num_rows($query) == 0) return false;
  1468.         $row = mysql_fetch_assoc($query);
  1469.         if($row['ban']) {
  1470.                 $prvreason = "Blacklisted ${row['field']} - " . htmlspecialchars($row['contents']);
  1471.                 auto_ban_poster($post['trip']?$post['nametrip']:$post['name'], $row['banlength'], 1, $prvreason, $row['banreason']);
  1472.         }
  1473.         error(S_UPFAIL, $dest);
  1474. }
  1475.  
  1476.  
  1477. // word-wrap without touching things inside of tags
  1478. function wordwrap2($str,$cols,$cut) {
  1479.         // if there's no runs of $cols non-space characters, wordwrap is a no-op
  1480.         if(strlen($str)<$cols || !preg_match('/[^ <>]{'.$cols.'}/', $str)) {
  1481.                 return $str;
  1482.         }
  1483.         $sections = preg_split('/[<>]/', $str);
  1484.         $str='';
  1485.         for($i=0;$i<count($sections);$i++) {
  1486.                 if($i%2) { // inside a tag
  1487.                         $str .= '<' . $sections[$i] . '>';
  1488.                 }
  1489.                 else { // outside a tag
  1490.                         $words = explode(' ',$sections[$i]);
  1491.                         foreach($words as &$word) {
  1492.                                 $word = wordwrap($word, $cols, $cut, 1);
  1493.                                 // fix utf-8 sequences (XXX: is this slower than mbstring?)
  1494.                                 $lines = explode($cut, $word);
  1495.                                 for($j=1;$j<count($lines);$j++) { // all lines except the first
  1496.                                         while(1) {
  1497.                                                 $chr = substr($lines[$j], 0, 1);
  1498.                                                 if((ord($chr) & 0xC0) == 0x80) { // if chr is a UTF-8 continuation...
  1499.                                                         $lines[$j-1] .= $chr; // put it on the end of the previous line
  1500.                                                         $lines[$j] = substr($lines[$j], 1); // take it off the current line
  1501.                                                         continue;
  1502.                                                 }
  1503.                                                         break; // chr was a beginning utf-8 character
  1504.                                         }
  1505.                                 }
  1506.                                 $word = implode($cut, $lines); 
  1507.                                
  1508.                         }
  1509.                         $str .= implode(' ', $words);
  1510.                 }
  1511.         }
  1512.         return $str;
  1513. }
  1514.  
  1515. function cidrtest ($longip, $CIDR) {
  1516.         list ($net, $mask) = split ("/", $CIDR);
  1517.        
  1518.         $ip_net = ip2long ($net);
  1519.         $ip_mask = ~((1 << (32 - $mask)) - 1);
  1520.        
  1521.         $ip_ip = $longip;
  1522.        
  1523.         $ip_ip_net = $ip_ip & $ip_mask;
  1524.        
  1525.         return ($ip_ip_net == $ip_net);
  1526. }
  1527.  
  1528. function  proxy_connect($port) {
  1529.   $fp = @fsockopen ($_SERVER["REMOTE_ADDR"], $port,$a,$b,2);
  1530.   if(!$fp){return 0;}else{return 1;}
  1531. }
  1532.  
  1533. function processlist_cleanup($id) {
  1534.         logtime('Done');
  1535.         //mysql_board_call("DELETE FROM proclist WHERE id='$id'");
  1536. }
  1537.  
  1538. function logtime($desc) {
  1539.         static $run = -1;
  1540.         if(!defined('PROFILING') && !defined('PROCESSLIST')) return;
  1541.         if($run==-1) {
  1542.                 $run = getmypid(); // rand(0,16777215);
  1543.                 if(PROCESSLIST == 1) {
  1544.                         register_shutdown_function('processlist_cleanup', $run);
  1545.                         $dump = mysql_real_escape_string(serialize(array('GET'=>$_GET,'POST'=>$_POST,'SERVER'=>$_SERVER)));
  1546.                         mysql_board_call("INSERT INTO proclist VALUES ('$run','$dump','')");
  1547.                 }
  1548.         }
  1549.         if(PROCESSLIST == 1) {
  1550.                 mysql_board_call("UPDATE proclist SET descr='$desc' WHERE id='$run'");
  1551.         }
  1552.         else {
  1553.                 $board = BOARD_DIR;
  1554.                 $time = microtime(true);
  1555.                 mysql_global_call("INSERT INTO prof_times VALUES ('$board',$run,$time,'$desc')");
  1556.         }
  1557. }
  1558.  
  1559. function make_american($com) {
  1560.         if (stripos($com, "america")!==FALSE) return $com; //already american
  1561.        
  1562.         $com = rtrim($com);
  1563.         $end = '!';
  1564.        
  1565.         if ($com == "") return $com;
  1566.  
  1567.         if (preg_match("/([.!?])$/", $com, $matches)) {$end = $matches[1]; $com = substr($com, 0, -1);}
  1568.        
  1569.         $com .= " IN AMERICA".$end;
  1570.        
  1571.         return $com;
  1572. }
  1573.  
  1574. /* Regist */
  1575. function regist($name,$email,$sub,$com,$url,$pwd,$upfile,$upfile_name,$resto,$age){
  1576.   global $path,$pwdc,$textonly,$admin,$spoiler,$dest;
  1577.   if ($pwd==ADMIN_PASS) $admin=$pwd;
  1578.   if ($admin!=ADMIN_PASS || !valid() ) $admin='';
  1579.   $mes="";
  1580.  
  1581.   if(!$upfile && !$resto) { // allow textonly threads for moderators!
  1582.         if(valid('textonly'))
  1583.                 $textonly = 1;
  1584.   }
  1585.   elseif(JANITOR_BOARD == 1) { // only allow mods/janitors to post, and textonly is always ok
  1586.         $textonly = 1;
  1587.         if(!valid('janitor_board'))
  1588.                 die();
  1589.   }
  1590.  
  1591.  
  1592.   // time
  1593.   $time = time();
  1594.   $tim = $time.substr(microtime(),2,3);
  1595.  
  1596.  /* logtime("locking tables: ".($resto?'reply':'thread').", ".($upfile?'image':'text'));
  1597.   if(PROCESSLIST == 1 && BOARD_DIR != 'b' && 0) {
  1598.         if(!mysql_board_call("LOCK TABLES ".SQLLOG." WRITE,proclist WRITE"))
  1599.                 die(S_SQLCONF.'<!--lk:'.mysql_errno().'-->');
  1600.   }
  1601.   else if(BOARD_DIR != 'b' && 0) {
  1602.   if(!mysql_board_call("LOCK TABLES ".SQLLOG." WRITE"))
  1603.         die(S_SQLCONF.'<!--lk:'.mysql_errno().'-->');
  1604. }
  1605.   logtime("got lock");*/
  1606.   $locked_time = time();
  1607.   mysql_board_call("set session query_cache_type=0");
  1608.   // check closed
  1609.   $resto=(int)$resto;
  1610.   if ($resto) {
  1611.     if(!$cchk=mysql_board_call("select closed from ".SQLLOG." where no=".$resto)){echo S_SQLFAIL;}
  1612.     list($closed)=mysql_fetch_row($cchk);
  1613.                 if ($closed==1&&!$admin) error("You can't reply to this thread anymore.",$upfile);
  1614.     mysql_free_result($cchk);
  1615.   }
  1616.  
  1617.         if(OEKAKI_BOARD == 1 && $_POST['oe_chk']) {
  1618.                 require_once 'oekaki.php';
  1619.                 oe_regist_check();
  1620.                 $upfile = realpath('tmp/' . $_POST['oe_ip'] . '.png');
  1621.                 $upfile_name = 'Oekaki';
  1622.                 $pchfile = realpath('tmp/' . $_POST['oe_ip'] . '.pch');
  1623.                 if(!file_exists($pchfile)) $pchfile = '';
  1624.         }
  1625.        
  1626.         $has_image = $upfile&&file_exists($upfile);
  1627.        
  1628.   if($has_image){
  1629.    // check image limit
  1630.         if ($resto) {
  1631.             if(!$result=mysql_board_call("select COUNT(*) from ".SQLLOG." where resto=$resto and fsize!=0")){echo S_SQLFAIL;}
  1632.             $countimgres=mysql_result($result,0,0);
  1633.       if ($countimgres>MAX_IMGRES) error("Max limit of ".MAX_IMGRES." image replies has been reached.",$upfile);
  1634.             mysql_free_result($result);
  1635.                 }
  1636.  
  1637.   //upload processing
  1638.         $dest = tempnam(substr($path,0,-1), "img");
  1639.         //$dest = $path.$tim.'.tmp';
  1640.         if(OEKAKI_BOARD == 1 && $_POST['oe_chk']) {
  1641.                 rename($upfile, $dest);
  1642.                 chmod($dest, 0644);
  1643.                 if($pchfile)
  1644.                         rename($pchfile, "$dest.pch");
  1645.         }
  1646.         else
  1647.                 move_uploaded_file($upfile, $dest);  
  1648.        
  1649.         clearstatcache(); // otherwise $dest looks like 0 bytes!
  1650.         logtime("Moved uploaded file");
  1651.        
  1652.     $upfile_name = CleanStr($upfile_name);
  1653.         $fsize=filesize($dest);
  1654.     if(!is_file($dest)) error(S_UPFAIL,$dest);
  1655.     if(!$fsize || $fsize>MAX_KB * 1024) error(S_TOOBIG,$dest);
  1656.  
  1657.     // PDF processing
  1658.     if(ENABLE_PDF==1 && strcasecmp('.pdf',substr($upfile_name,-4))==0) {
  1659.         $ext='.pdf';
  1660.         $W=$H=1;       
  1661.         $md5 = md5_of_file($dest);
  1662.         // run through ghostscript to check for validity
  1663.         if(pclose(popen("/usr/local/bin/gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=nullpage $dest",'w'))) { error(S_UPFAIL,$dest); }
  1664.     } else {
  1665.     $size = getimagesize($dest);
  1666.     if(!is_array($size)) error(S_NOREC,$dest);
  1667.     $md5 = md5_of_file($dest);
  1668.  
  1669.     //chmod($dest,0666);
  1670.     $W = $size[0];
  1671.     $H = $size[1];
  1672.     switch ($size[2]) {
  1673.       case 1 : $ext=".gif";break;
  1674.       case 2 : $ext=".jpg";break;
  1675.       case 3 : $ext=".png";break;
  1676.       case 4 : $ext=".swf";error(S_UPFAIL,$dest);break;
  1677.       case 5 : $ext=".psd";error(S_UPFAIL,$dest);break;
  1678.       case 6 : $ext=".bmp";error(S_UPFAIL,$dest);break;
  1679.       case 7 : $ext=".tiff";error(S_UPFAIL,$dest);break;
  1680.       case 8 : $ext=".tiff";error(S_UPFAIL,$dest);break;
  1681.       case 9 : $ext=".jpc";error(S_UPFAIL,$dest);break;
  1682.       case 10 : $ext=".jp2";error(S_UPFAIL,$dest);break;
  1683.       case 11 : $ext=".jpx";error(S_UPFAIL,$dest);break;
  1684.       case 13 : $ext=".swf";error(S_UPFAIL,$dest);break;
  1685.       default : $ext=".xxx";error(S_UPFAIL,$dest);break;
  1686.     }
  1687.     if(GIF_ONLY == 1 && $size[2] != 1) error(S_UPFAIL,$dest);
  1688.         } // end PDF processing -else
  1689.                 $insfile=substr($upfile_name, 0, -strlen($ext));
  1690.                
  1691.         spam_filter_post_image($name, $dest, $md5, $upfile_name, $ext);
  1692.  
  1693.     // Picture reduction
  1694.     if (!$resto) {
  1695.             $maxw = MAX_W;
  1696.             $maxh = MAX_H;
  1697.     } else {
  1698.             $maxw = MAXR_W;
  1699.             $maxh = MAXR_H;
  1700.                 }
  1701.         if (defined('MIN_W') && MIN_W > $W) error(S_UPFAIL,$dest);
  1702.         if (defined('MIN_H') && MIN_H > $H) error(S_UPFAIL,$dest);
  1703.         if(defined('MAX_DIMENSION'))
  1704.                 $maxdimension = MAX_DIMENSION;
  1705.         else
  1706.                 $maxdimension = 5000;
  1707.     if ($W > $maxdimension || $H > $maxdimension) {
  1708.             error(S_TOOBIGRES,$dest);
  1709.     } elseif($W > $maxw || $H > $maxh){
  1710.       $W2 = $maxw / $W;
  1711.       $H2 = $maxh / $H;
  1712.       ($W2 < $H2) ? $key = $W2 : $key = $H2;
  1713.       $TN_W = ceil($W * $key);
  1714.       $TN_H = ceil($H * $key);
  1715.     }
  1716.     $mes = $upfile_name . ' ' . S_UPGOOD;
  1717.   }
  1718.  
  1719. if(OEKAKI_BOARD == 1 && $_POST['oe_chk']) {
  1720. }
  1721. else {
  1722.   if($_FILES["upfile"]["error"]>0){
  1723.         if($_FILES["upfile"]["error"]==UPLOAD_ERR_INI_SIZE)
  1724.             error(S_TOOBIG,$dest);
  1725.         if($_FILES["upfile"]["error"]==UPLOAD_ERR_FORM_SIZE)
  1726.             error(S_TOOBIG,$dest);
  1727.         if($_FILES["upfile"]["error"]==UPLOAD_ERR_PARTIAL)
  1728.             error(S_UPFAIL,$dest);
  1729.         if($_FILES["upfile"]["error"]==UPLOAD_ERR_CANT_WRITE)
  1730.             error(S_UPFAIL,$dest);
  1731.   }
  1732.  
  1733.   if($upfile_name&&$_FILES["upfile"]["size"]==0){
  1734.     error(S_TOOBIGORNONE,$dest);
  1735.   }
  1736. }
  1737.  
  1738. if(ENABLE_EXIF==1) {
  1739.         $exif = htmlspecialchars(shell_exec("/usr/local/bin/exiftags $dest"));
  1740. }
  1741.  
  1742.   //The last result number
  1743.   $lastno = mysql_result(mysql_board_call("select max(no) from ".SQLLOG),0,0);
  1744.  
  1745.   $resto=(int)$resto;
  1746.   if($resto){
  1747.         if (!mysql_result(mysql_board_call("select count(no) from ".SQLLOG." where root>0 and no=$resto"),0,0))
  1748.                 error(S_NOTHREADERR,$dest);
  1749.   }
  1750.  
  1751.   if($_SERVER["REQUEST_METHOD"] != "POST") error(S_UNJUST,$dest);
  1752.   // Form content check
  1753.   if(!$name||ereg("^[ |&#12288;|]*$",$name)) $name="";
  1754.   if(!$com||ereg("^[ |&#12288;|\t]*$",$com)) $com="";
  1755.   if(!$sub||ereg("^[ |&#12288;|]*$",$sub))   $sub="";
  1756.  
  1757.   if(NO_TEXTONLY==1 && !$admin) {
  1758.     if(!$resto&&!$has_image) error(S_NOPIC,$dest);
  1759.   } else {
  1760.     if(!$resto&&!$textonly&&!$has_image) error(S_NOPIC,$dest);
  1761.   }
  1762.   if(!trim($com) && !$has_image) error(S_NOTEXT,$dest);
  1763.  
  1764.  $name=ereg_replace(S_MANAGEMENT,"\"".S_MANAGEMENT."\"",$name);
  1765.  $name=ereg_replace(S_DELETION,"\"".S_DELETION."\"",$name);
  1766.  
  1767. if(!$admin && strlen($com) > 2000) error(S_TOOLONG,$dest);
  1768. if(strlen($name) > 100) error(S_TOOLONG,$dest);
  1769. if(strlen($email) > 100) error(S_TOOLONG,$dest);
  1770. if(strlen($sub) > 100) error(S_TOOLONG,$dest);
  1771. if(strlen($resto) > 10) error(S_UNUSUAL,$dest);
  1772. if(strlen($url) > 10) error(S_UNUSUAL,$dest);
  1773.  
  1774. logtime("starting autoban checks");
  1775.         spam_filter_post_content($com, $sub, $name, $fsize, $resto, $W, $H, $dest, $upfile_name, $email);
  1776.        
  1777.   //host check
  1778.   //$host = gethostbyaddr($_SERVER["REMOTE_ADDR"]);
  1779.   $host = $_SERVER["REMOTE_ADDR"];
  1780.  
  1781.   //lol /b/
  1782.   $xff = getenv("HTTP_X_FORWARDED_FOR");
  1783.  
  1784.         spam_filter_post_ip($dest);
  1785.        
  1786.         logtime("inserting xff");
  1787.         if (SAVE_XFF==1&&getenv("HTTP_X_FORWARDED_FOR")) {
  1788.         mysql_global_do(sprintf("INSERT INTO xff (tim,board,host) VALUES ('%s','%s','%s')", $tim,BOARD_DIR,mysql_escape_string(getenv("HTTP_X_FORWARDED_FOR"))) );
  1789.         }
  1790.  
  1791.  
  1792.   // No, path, time, and url format
  1793.   if($pwd==""){
  1794.     if($pwdc==""){
  1795.       $pwd=rand();$pwd=substr($pwd,0,8);
  1796.     }else{
  1797.       $pwd=$pwdc;
  1798.     }
  1799.   }
  1800.  
  1801.   $c_pass = $pwd;
  1802.   $pass = ($pwd) ? substr(md5($pwd),2,8) : "*";
  1803.  $youbi = array(S_SUN, S_MON, S_TUE, S_WED, S_THU, S_FRI, S_SAT);
  1804.   $yd = $youbi[date("w", $time)] ;
  1805.   if(SHOW_SECONDS == 1) {
  1806.           $now = date("m/d/y",$time)."(".(string)$yd.")".date("H:i:s",$time);
  1807.   } else {
  1808.           $now = date("m/d/y",$time)."(".(string)$yd.")".date("H:i",$time);
  1809.   }
  1810.   if(DISP_ID){
  1811.     if($email&&DISP_ID==1){
  1812.       $now .= " ID:???";
  1813.     }else{
  1814.       $now.=" ID:".substr(crypt(md5($_SERVER["REMOTE_ADDR"].'id'.date("Ymd", $time)),'id'),+3);
  1815.     }
  1816.   }
  1817.  
  1818.   $c_name = $name;
  1819.   $c_email = $email;
  1820.  
  1821.   if(JANITOR_BOARD == 1) { // now that the cookie_name and _email are separated, we can modify the real ones
  1822.         $name = $_COOKIE['4chan_auser'];
  1823.         $email = '';
  1824.   }
  1825.  
  1826.   //Text plastic surgery (rorororor)
  1827.   $email= CleanStr($email);  $email=ereg_replace("[\r\n]","",$email);
  1828.   $sub  = CleanStr($sub);    $sub  =ereg_replace("[\r\n]","",$sub);
  1829.   $url  = CleanStr($url);    $url  =ereg_replace("[\r\n]","",$url);
  1830.   $resto= CleanStr($resto);  $resto=ereg_replace("[\r\n]","",$resto);
  1831.   $com  = CleanStr($com,1);
  1832.  
  1833.   if(SPOILERS==1&&$spoiler) {
  1834.         $sub = "SPOILER<>$sub";
  1835.   }
  1836.   // Standardize new character lines
  1837.   $com = str_replace( "\r\n",  "\n", $com);
  1838.   $com = str_replace( "\r",  "\n", $com);
  1839.   //$com = preg_replace("/\A([0-9A-Za-z]{10})+\Z/", "!s8AAL8z!", $com);
  1840.   // Continuous lines
  1841.   $com = ereg_replace("\n((&#12288;| )*\n){3,}","\n",$com);
  1842.  
  1843.   if(!$admin && substr_count($com,"\n")>MAX_LINES) error("Error: Too many lines.",$dest);
  1844.  
  1845.   $com = nl2br($com);           //br is substituted before newline char
  1846.  
  1847.   $com = str_replace("\n",  "", $com);  //\n is erased
  1848.  
  1849. if(ROBOT9000==1) {  
  1850.    include '/www/global/plugins/robot9000.php';  
  1851.    $r9k = robot9000($r9kname,$email,$sub,$com,$md5,ip2long($host),valid('floodbypass'));  
  1852.    if($r9k != "ok") error($r9k, $dest);  
  1853. }
  1854.         if(ENABLE_EXIF==1 && $exif) {
  1855.                 //turn exif into a table
  1856.                 $exiflines = explode("\n",$exif);
  1857.                 $exif = "<table class=\"exif\" id=\"exif$tim\" style=\"display:none;\">";
  1858.                 foreach($exiflines as $exifline) {
  1859.                         list($exiftag,$exifvalue) = explode(': ',$exifline);
  1860.                         if($exifvalue != '')
  1861.                                 $exif .= "<tr><td>$exiftag</td><td>$exifvalue</td></tr>";
  1862.                         else
  1863.                                 $exif .= "<tr><td><b>$exiftag</b></td></tr>";
  1864.                 }
  1865.                 $exif .= '</table>';
  1866.                 $com .= "<br/><span class=\"abbr\">EXIF data available. Click <a href=\"javascript:void(0)\" onclick=\"toggle('exif$tim')\">here</a> to show/hide.</span><br/>";
  1867.                 $com .= "$exif";
  1868.         }
  1869.         if(OEKAKI_BOARD==1 && $_POST['oe_chk']) {
  1870.                 $com .= oe_info($dest,$tim);
  1871.         }
  1872.  
  1873.   //$name=ereg_replace("&#9670;","&#9671;",$name);  //replace filled diamond with hollow diamond (sjis)
  1874.   $name=ereg_replace("[\r\n]","",$name);
  1875.   $names=iconv("UTF-8", "CP932//IGNORE", $name); // convert to Windows Japanese #&#65355;&#65345;&#65357;&#65353;
  1876.  
  1877.   //start new tripcode crap
  1878.         list ($name) = explode("#", $name);
  1879.     $name = CleanStr($name);
  1880.  
  1881.         if(preg_match("/\#+$/", $names)){
  1882.             $names = preg_replace("/\#+$/", "", $names);
  1883.         }
  1884.         if (preg_match("/\#/", $names)) {
  1885.             $names = str_replace("&#","&&",htmlspecialchars($names)); # otherwise HTML numeric entities screw up explode()!
  1886.             list ($nametemp,$trip,$sectrip) = str_replace("&&", "&#", explode("#",$names,3));
  1887.             $names = $nametemp;
  1888.             $name .= "</span>";
  1889.  
  1890.             if ($trip != "") {
  1891.                 if (FORTUNE_TRIP == 1 && $trip == "fortune") {
  1892.                         $fortunes = array("Bad Luck","Average Luck","Good Luck","Excellent Luck","Reply hazy, try again","Godly Luck","Very Bad Luck","Outlook good","Better not tell you now","You will meet a dark handsome stranger","&#65399;&#65408;&#9473;&#9473;&#9473;&#9473;&#9473;&#9473;(&#65439;&#8704;&#65439;)&#9473;&#9473;&#9473;&#9473;&#9473;&#9473; !!!!","&#65288;&#12288;´_&#12445;`&#65289;&#65420;&#65392;&#65437; ","Good news will come to you by mail");
  1893.                         $fortunenum = rand(0,sizeof($fortunes)-1);
  1894.                         $fortcol = "#" . sprintf("%02x%02x%02x",
  1895.                                 127+127*sin(2*M_PI * $fortunenum / sizeof($fortunes)),
  1896.                                 127+127*sin(2*M_PI * $fortunenum / sizeof($fortunes)+ 2/3 * M_PI),
  1897.                                 127+127*sin(2*M_PI * $fortunenum / sizeof($fortunes) + 4/3 * M_PI));
  1898.                         $com = "<font color=$fortcol><b>Your fortune: ".$fortunes[$fortunenum]."</b></font><br /><br />".$com;
  1899.                         $trip = "";
  1900.                         if($sectrip == "") {
  1901.                                 if($name == "</span>" && $sectrip == "")
  1902.                                         $name = S_ANONAME;
  1903.                                 else
  1904.                                         $name = str_replace("</span>","",$name);       
  1905.                 }
  1906.             } else if($trip=="fortune") {
  1907.                 //remove fortune even if FORTUNE_TRIP is off
  1908.                 $trip="";
  1909.                 if($sectrip == "") {
  1910.                         if($name == "</span>" && $sectrip == "")
  1911.                                 $name = S_ANONAME;
  1912.                         else
  1913.                                 $name = str_replace("</span>","",$name);
  1914.                 }
  1915.  
  1916.             } else {
  1917.  
  1918.                 $salt = strtr(preg_replace("/[^\.-z]/",".",substr($trip."H.",1,2)),":;<=>?@[\\]^_`","ABCDEFGabcdef");
  1919.                 $trip = substr(crypt($trip, $salt),-10);
  1920.                 $name.=" <span class=\"postertrip\">!".$trip;
  1921.                 }
  1922.             }
  1923.  
  1924.  
  1925.             if ($sectrip != "") {
  1926.                 $salt = "LOLLOLOLOLOLOLOLOLOLOLOLOLOLOLOL"; #this is ONLY used if the host doesn't have openssl
  1927.                                                         #I don't know a better way to get random data
  1928.             if (file_exists(SALTFILE)) { #already generated a key
  1929.                 $salt = file_get_contents(SALTFILE);
  1930.             } else {
  1931.                 system("openssl rand 448 > '".SALTFILE."'",$err);
  1932.                 if ($err === 0) {
  1933.                     chmod(SALTFILE,0400);
  1934.                     $salt = file_get_contents(SALTFILE);
  1935.                 }
  1936.             }
  1937.                 $sha = base64_encode(pack("H*",sha1($sectrip.$salt)));
  1938.                 $sha = substr($sha,0,11);
  1939.                             if($trip=="") $name.=" <span class=\"postertrip\">";
  1940.                             $name.="!!".$sha;
  1941.             }
  1942.         } //end new tripcode crap
  1943.  
  1944.         if(!$name) $name=S_ANONAME;
  1945.         if(!$com) $com=S_ANOTEXT;
  1946.         if(!$sub) $sub=S_ANOTITLE;
  1947.  
  1948.         if(DICE_ROLL==1) {
  1949.         if ($email) {
  1950.                 if (preg_match("/dice[ +](\\d+)[ d+](\\d+)(([ +-]+?)(-?\\d+))?/", $email, $match)) {
  1951.                         $dicetxt = "rolled ";
  1952.                         $dicenum = min(25, $match[1]);
  1953.                         $diceside = $match[2];
  1954.                         $diceaddexpr = $match[3];
  1955.                         $dicesign = $match[4];
  1956.                         $diceadd = intval($match[5]);
  1957.                        
  1958.                         for ($i = 0; $i < $dicenum; $i++) {
  1959.                                 $dicerand = mt_rand(1, $diceside);
  1960.                                 if ($i) $dicetxt .= ", ";
  1961.                                 $dicetxt .= $dicerand;
  1962.                                 $dicesum += $dicerand;
  1963.                         }
  1964.                        
  1965.                         if ($diceaddexpr) {
  1966.                                 if (strpos($dicesign, "-") > 0) $diceadd *= -1;
  1967.                                 $dicetxt .= ($diceadd >= 0 ? " + " : " - ").abs($diceadd);
  1968.                                 $dicesum += $diceadd;
  1969.                         }
  1970.                        
  1971.                         $dicetxt .= " = $dicesum<br /><br />";
  1972.                         $com = "<b>$dicetxt</b>".$com;
  1973.                 }
  1974.         }
  1975.         }
  1976.         $emails=$email;
  1977.   if(ereg("(#|&#65283;)(.*)",$emails,$regs)){
  1978.     if ($regs[2]=="pubies") {
  1979.         list($email)=explode("#",$email,2);
  1980.         if(valid()) {
  1981.               $color1="#800080";
  1982.               $color2="#900090";
  1983.               $ma="Mod";
  1984.               if(stristr($name,"moot")||stristr($name,"coda")) {
  1985.                 $color1="#F00000";
  1986.                 $color2="#FF0000";
  1987.                 $ma="Admin";
  1988.               }
  1989.               $name="<span title='$email' style=\"color:$color1\">".$name;
  1990.               $name=str_replace(" <span class=\"postertrip\">","</span> <span class=\"postertrip\"><span title='$email' style=\"color:$color2;font-weight:normal\">",$name);
  1991.               $name.="</span></span> <span class=\"commentpostername\"><span title='$email' style=\"color:$color1\">## $ma</span>";
  1992.       }
  1993.         $email = '';
  1994.  /*   } elseif ($regs[2]=="munroexkcd") {
  1995.             $name="<span style=\"color:#0000F0\">".$name;
  1996.             $name=str_replace(" <span class=\"postertrip\">","</span> <span class=\"postertrip\"><span style=\"color:#0000FF;font-weight:normal\">",$name);
  1997.             $name.="</span></span> <span class=\"commentpostername\"><span style=\"color:#0000F0\">## BlOgGeR</span>";
  1998.       list($email)=explode("#",$email,2);
  1999.     } elseif ($regs[2]=="netkingdongs") {
  2000.             $name='</span> <span class="postertrip">!!NETKING...';
  2001.             list($email)=explode("#",$email,2);
  2002.     } elseif ($regs[2]=="redhammer") {
  2003.         if(!valid()) auto_ban("<b>autobanmenow</b>",$name,"redhammer capcode");
  2004.       list($email)=explode("#",$email,2); */
  2005.     }
  2006.   }
  2007.  
  2008.         $nameparts=explode('</span> <span class="postertrip">!',$name);
  2009.         check_blacklist(array(
  2010.                 'name' => $nameparts[0],
  2011.                 'trip' => $trip,
  2012.                 'nametrip' => "{$nameparts[0]} #{$trip}",
  2013.                 'md5' => $md5,
  2014.                 'email' => $email,
  2015.                 'sub' => $sub,
  2016.                 'com' => $com,
  2017.                 'pwd' => $pass,
  2018.                 'xff' => $xff,
  2019.                 'filename' => $insfile,
  2020.                 ), $dest);
  2021.  
  2022.         spam_filter_post_trip($name, $trip, $dest);
  2023.        
  2024.         if(SPOILERS==1) {
  2025.                 $com = spoiler_parse($com);
  2026.         }
  2027.         if(SAGE_FILTER==1&&(stripos($sub,"sage")!==FALSE||stripos($com,"sage")!==FALSE)&&stripos($email,"sage")!==FALSE) $email=""; //lol /b/
  2028.         if(WORD_FILT&&file_exists("wf.php")){
  2029.                 $com = word_filter($com,"com");
  2030.                 if($sub)
  2031.                         $sub = word_filter($sub,"sub");
  2032.                 $com = str_replace(":getprophet:",$no,$com);
  2033.                 $namearr=explode('</span> <span class="postertrip">',$name);
  2034.                 if (strstr($name,'</span> <span class="postertrip">')) { $nametrip='</span> <span class="postertrip">'.$namearr[1]; } else { $nametrip=""; }
  2035.                 if($namearr[0] != S_ANONAME)
  2036.                         $name = word_filter($namearr[0],"name").$nametrip;
  2037.         }
  2038.  
  2039.         if(FORCED_ANON==1) {$name = "</span>$now<span>"; $sub = ''; $now = '';}
  2040.         $com = wordwrap2($com, 100, "<br />");
  2041.         $com = preg_replace("!(^|>)(&gt;[^<]*)!", "\\1<font class=\"unkfunc\">\\2</font>", $com);
  2042.        
  2043.         $is_sage = stripos($email, "sage") !== FALSE;
  2044.         //post is now completely created(?)
  2045.  
  2046.         logtime("Before flood check");
  2047.         $may_flood = valid('floodbypass');
  2048.        
  2049.         if (!$may_flood) {
  2050.                 if ($com) {
  2051.                         // Check for duplicate comments
  2052.                         $query="select count(no)>0 from ".SQLLOG." where com='".mysql_escape_string($com)."' ".
  2053.                                 "and host='".mysql_escape_string($host)."' ".
  2054.                                 "and time>".($time-RENZOKU_DUPE);
  2055.                         $result=mysql_board_call($query);
  2056.                         if(mysql_result($result,0,0))error(S_RENZOKU,$dest);
  2057.                         mysql_free_result($result);
  2058.                 }
  2059.  
  2060.                 if (!$has_image) {
  2061.                         // Check for flood limit on replies
  2062.                         $query="select count(no)>0 from ".SQLLOG." where time>".($time - RENZOKU)." ".
  2063.                                 "and host='".mysql_escape_string($host)."' and resto>0";
  2064.                         $result=mysql_board_call($query);
  2065.                         if(mysql_result($result,0,0))error(S_RENZOKU, $dest);
  2066.                         mysql_free_result($result);
  2067.                 }
  2068.                
  2069.                 if ($is_sage) {
  2070.                         // Check flood limit on sage posts
  2071.                         $query="select count(no)>0 from ".SQLLOG." where time>".($time - RENZOKU_SAGE)." ".
  2072.                                 "and host='".mysql_escape_string($host)."' and resto>0 and permasage=1";
  2073.                         $result=mysql_board_call($query);
  2074.                         if(mysql_result($result,0,0))error(S_RENZOKU, $dest);
  2075.                         mysql_free_result($result);
  2076.                 }
  2077.                
  2078.                 if (!$resto) {
  2079.                         // Check flood limit on new threads
  2080.                         $query="select count(no)>0 from ".SQLLOG." where time>".($time - RENZOKU3)." ".
  2081.                                 "and host='".mysql_escape_string($host)."' and root>0"; //root>0 == non-sticky
  2082.                         $result=mysql_board_call($query);
  2083.                         if(mysql_result($result,0,0))error(S_RENZOKU3, $dest);
  2084.                         mysql_free_result($result);
  2085.                 }
  2086.         }
  2087.  
  2088.         // Upload processing
  2089.         if($has_image) {
  2090.                 if(!$may_flood) {
  2091.                         $query="select count(no)>0 from ".SQLLOG." where time>".($time - RENZOKU2)." ".
  2092.                                 "and host='".mysql_escape_string($host)."' and resto>0";
  2093.                         $result=mysql_board_call($query);
  2094.                         if(mysql_result($result,0,0))error(S_RENZOKU2,$dest);
  2095.                         mysql_free_result($result);
  2096.                 }
  2097.  
  2098.                 //Duplicate image check
  2099.                 $result = mysql_board_call("select no,resto from ".SQLLOG." where md5='$md5'");
  2100.                 if(mysql_num_rows($result)){
  2101.                         list($dupeno,$duperesto) = mysql_fetch_row($result);
  2102.                         if(!$duperesto) $duperesto = $dupeno;
  2103.                         error('<a href="'.DATA_SERVER . BOARD_DIR . "/res/" . $duperesto . PHP_EXT . '#' . $dupeno . '">'.S_DUPE.'</a>',$dest);
  2104.                 }
  2105.                 mysql_free_result($result);
  2106.         }
  2107.  
  2108.    $rootqu = $resto ? "0" : "now()";
  2109.  
  2110.         // thumbnail
  2111.   if($has_image){
  2112.     rename($dest,$path.$tim.$ext);
  2113.     if(USE_THUMB){
  2114.                 $tn_name = thumb($path,$tim,$ext,$resto);
  2115.                 if (!$tn_name && $ext != ".pdf") {
  2116.                         error(S_UNUSUAL);
  2117.                 }
  2118.                 }
  2119.     if(OEKAKI_BOARD == 1 && $_POST['oe_chk']) {
  2120.         rename("$dest.pch",$path.$tim.'.pch');
  2121.         unlink($upfile); // get rid of the tmp/ entries
  2122.         unlink($pchfile);
  2123.     }
  2124.   }
  2125. logtime("Thumbnail created");
  2126.  
  2127.         logtime("Before insertion");
  2128.         // noko (stay) actions
  2129.         if($email == 'noko') {
  2130.                 $email = ''; $noko = 1;
  2131.         }
  2132.         else if($email == 'noko2') {
  2133.                 $email = ''; $noko = 2;
  2134.         }
  2135.        
  2136.         //find sticky & autosage
  2137.         // auto-sticky
  2138.         $sticky = false;
  2139.         $autosage = spam_filter_should_autosage($com, $sub, $name, $fsize, $resto, $W, $H, $dest, $insertid);
  2140.        
  2141.         if(defined('AUTOSTICKY') && AUTOSTICKY) {
  2142.                 $autosticky = preg_split("/,\s*/", AUTOSTICKY);
  2143.                 if($resto == 0) {
  2144.                         if($insertid % 1000000 == 0 || in_array($insertid,$autosticky))
  2145.                                 $sticky = true;
  2146.                 }
  2147.         }
  2148.        
  2149.         $flag_cols = "";
  2150.         $flag_vals = "";
  2151.        
  2152.         if ($sticky) {
  2153.                 $flag_cols = ",sticky";
  2154.                 $flag_vals = ",1";
  2155.         }
  2156.        
  2157.         //permasage just means "is sage" for replies
  2158.         if ($resto ? $is_sage : $autosage) {
  2159.                 $flag_cols .= ",permasage";
  2160.                 $flag_vals .= ",1";
  2161.         }
  2162.        
  2163.   $query="insert into ".SQLLOG." (now,name,email,sub,com,host,pwd,filename,ext,w,h,tn_w,tn_h,tim,time,md5,fsize,root,resto$flag_cols) values (".
  2164. "'".$now."',".
  2165. "'".mysql_escape_string($name)."',".
  2166. "'".mysql_escape_string($email)."',".
  2167. "'".mysql_escape_string($sub)."',".
  2168. "'".mysql_escape_string($com)."',".
  2169. "'".mysql_escape_string($host)."',".
  2170. "'".mysql_escape_string($pass)."',".
  2171. "'".mysql_escape_string($insfile)."',".
  2172. "'".$ext."',".
  2173. (int)$W.",".
  2174. (int)$H.",".
  2175. (int)$TN_W.",".
  2176. (int)$TN_H.",".
  2177. "'".$tim."',".
  2178. (int)$time.",".
  2179. "'".$md5."',".
  2180. (int)$fsize.",".
  2181. $rootqu.",".
  2182. (int)$resto.
  2183. $flag_vals.")";
  2184.   if(!$result=mysql_board_call($query)){echo S_SQLFAIL;}  //post registration
  2185.  
  2186.         $cookie_domain = (NOT4CHAN==1)?'.not4chan.org':'.4chan.org';
  2187.   //Cookies
  2188.   setrawcookie("4chan_name", rawurlencode($c_name), time()+($c_name?(7*24*3600):-3600),'/',$cookie_domain);
  2189.   //header("Set-Cookie: 4chan_name=$c_name; expires=".date("D, d-M-Y H:i:s",time()+7*24*3600)." GMT",false);
  2190.   if (($c_email!="sage")&&($c_email!="age")){
  2191.         setcookie ("4chan_email", $c_email,time()+($c_email?(7*24*3600):-3600),'/',$cookie_domain);  // 1 week cookie expiration
  2192.   }
  2193.   setcookie("4chan_pass", $c_pass,time()+7*24*3600,'/',$cookie_domain);  // 1 week cookie expiration
  2194.  
  2195.   $insertid = mysql_board_insert_id();
  2196.        
  2197.         if($resto){ //sage or age action
  2198.                 $resline=mysql_board_call("select count(no) from ".SQLLOG." where resto=".$resto);
  2199.                 $countres=mysql_result($resline,0,0);
  2200.                 mysql_free_result($resline);
  2201.                 $resline=mysql_board_call("select sticky,permasage from ".SQLLOG." where no=".$resto);
  2202.                 list($stuck,$psage)=mysql_fetch_row($resline);
  2203.                 mysql_free_result($resline);
  2204.                 if((stripos($email,'sage')===FALSE && $countres < MAX_RES && $stuck != "1" && $psage != "1") || ($admin&&$age&&$stuck != "1")){
  2205.                         $query="update ".SQLLOG." set root=now() where no=$resto"; //age
  2206.                         mysql_board_call($query);
  2207.                 }
  2208.         }
  2209.        
  2210.         $static_rebuild = defined("STATIC_REBUILD") && (STATIC_REBUILD==1);
  2211.         logtime("Before trim_db");  
  2212.         // trim database
  2213.         if(!$resto && !$static_rebuild)
  2214.           trim_db();
  2215.         logtime("After trim_db");
  2216. if(PROCESSLIST == 1 && (time() > ($locked_time+7))) {
  2217.                         $dump = mysql_real_escape_string(serialize(array('GET'=>$_GET,'POST'=>$_POST,'SERVER'=>$_SERVER)));
  2218.                         mysql_board_call("INSERT INTO proclist VALUES (connection_id(),'$dump','slow post')");
  2219. }
  2220. /*mysql_board_unlock();
  2221.  
  2222.         logtime("Tables unlocked");     */
  2223. if(BOARD_DIR == 'b')
  2224. iplog_add(BOARD_DIR, $insertid, $host);
  2225.         logtime("Ip logged");
  2226.  
  2227. if(RAPIDSEARCH_LOGGING == 1) {
  2228.         rapidsearch_check(BOARD_DIR, $insertid, $com);
  2229. }
  2230.         logtime("rapidsearch check finished");
  2231.  
  2232.         $deferred = false;
  2233.         // update html
  2234.         if($resto) {
  2235.         $deferred = updatelog($resto, $static_rebuild);
  2236.         } else {
  2237.           $deferred = updatelog($insertid, $static_rebuild);
  2238.   }
  2239.   logtime("Pages rebuilt");
  2240.   // determine url to redirect to
  2241.         if($noko && !$resto) {
  2242.                 $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $insertid . PHP_EXT;
  2243.         }
  2244.         else if($noko==1) {
  2245.                 $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $resto . PHP_EXT . '#' . $insertid;    
  2246.         }
  2247.         else {
  2248.                 $redirect = PHP_SELF2_ABS;
  2249.         }
  2250.  
  2251.   if($deferred) {
  2252.         echo "<html><head><META HTTP-EQUIV=\"refresh\" content=\"2;URL=$redirect\"></head>";
  2253.         echo "<body>$mes ".S_SCRCHANGE."<br>Your post may not appear immediately.<!-- thread:$resto,no:$insertid --></body></html>";
  2254.   }
  2255.   else {
  2256.         echo "<html><head><META HTTP-EQUIV=\"refresh\" content=\"1;URL=$redirect\"></head>";
  2257.         echo "<body>$mes ".S_SCRCHANGE."<!-- thread:$resto,no:$insertid --></body></html>";
  2258.   }
  2259.  
  2260. }
  2261.  
  2262. function resredir($res) {
  2263.         $res = (int)$res;
  2264.         mysql_board_lock();
  2265.         if(!$redir=mysql_board_call("select no,resto from ".SQLLOG." where no=".$res)){echo S_SQLFAIL;}
  2266.         list($no,$resto)=mysql_fetch_row($redir);
  2267.         if(!$no) {
  2268.                 $maxq = mysql_board_call("select max(no) from ".SQLLOG."");
  2269.                 list($max)=mysql_fetch_row($maxq);
  2270.                 if(!$max || ($res > $max))
  2271.                         header("HTTP/1.0 404 Not Found");
  2272.                 else // res < max, so it must be deleted!
  2273.                         header("HTTP/1.0 410 Gone");
  2274.                 error(S_NOTHREADERR,$dest);
  2275.         }
  2276.  
  2277.   if($resto=="0") // thread
  2278.         $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $no . PHP_EXT . '#' . $no;
  2279.   else
  2280.         $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $resto . PHP_EXT . '#' . $no;  
  2281.  
  2282.        
  2283.         echo "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=$redirect\">";
  2284.         if($resto=="0")
  2285.                 log_cache();
  2286.         mysql_board_unlock();
  2287.        
  2288.         if($resto=="0") { // thread
  2289.                 updatelog($res);
  2290.         }
  2291. }
  2292.  
  2293. //thumbnails
  2294. function thumb($path,$tim,$ext,$resto){
  2295.   if(!function_exists("ImageCreate")||!function_exists("ImageCreateFromJPEG"))return;
  2296.   $fname=$path.$tim.$ext;
  2297.   $thumb_dir = THUMB_DIR;     //thumbnail directory
  2298.   $outpath = $thumb_dir.$tim.'s.jpg';
  2299.   if (!$resto) {
  2300.           $width     = MAX_W;            //output width
  2301.           $height    = MAX_H;            //output height
  2302.   } else {
  2303.           $width     = MAXR_W;            //output width (imgreply)
  2304.           $height    = MAXR_H;            //output height (imgreply)
  2305.   }
  2306.   // width, height, and type are aquired
  2307.   if(ENABLE_PDF==1 && $ext=='.pdf') {
  2308.         // create jpeg for the thumbnailer
  2309.         $pdfjpeg = $path.$tim.'.pdf.tmp';
  2310.         @exec("/usr/local/bin/gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=jpeg -sOutputFile=$pdfjpeg $fname");
  2311.         if(!file_exists($pdfjpeg)) unlink($fname);
  2312.         $fname = $pdfjpeg;
  2313.   }
  2314.   $size = GetImageSize($fname);
  2315.   $memory_limit_increased = false;
  2316.   if($size[0]*$size[1] > 3000000) {
  2317.         $memory_limit_increased = true;
  2318.           ini_set('memory_limit', memory_get_usage() + $size[0]*$size[1]*10); // for huge images
  2319.   }
  2320.   switch ($size[2]) {
  2321.     case 1 :
  2322.       if(function_exists("ImageCreateFromGIF")){
  2323.         $im_in = ImageCreateFromGIF($fname);
  2324.         if($im_in){break;}
  2325.       }
  2326.       if(!is_executable(realpath("/www/global/gif2png"))||!function_exists("ImageCreateFromPNG"))return;
  2327.       @exec(realpath("/www/global/gif2png")." $fname",$a);
  2328.       if(!file_exists($path.$tim.'.png'))return;
  2329.       $im_in = ImageCreateFromPNG($path.$tim.'.png');
  2330.       unlink($path.$tim.'.png');
  2331.       if(!$im_in)return;
  2332.       break;
  2333.     case 2 : $im_in = ImageCreateFromJPEG($fname);
  2334.       if(!$im_in){return;}
  2335.        break;
  2336.     case 3 :
  2337.       if(!function_exists("ImageCreateFromPNG"))return;
  2338.       $im_in = ImageCreateFromPNG($fname);
  2339.       if(!$im_in){return;}
  2340.       break;
  2341.     default : return;
  2342.   }
  2343.   // Resizing
  2344.   if ($size[0] > $width || $size[1] > $height || $size[2]==1) {
  2345.     $key_w = $width / $size[0];
  2346.     $key_h = $height / $size[1];
  2347.     ($key_w < $key_h) ? $keys = $key_w : $keys = $key_h;
  2348.     $out_w = ceil($size[0] * $keys) +1;
  2349.     $out_h = ceil($size[1] * $keys) +1;
  2350.     /*if ($size[2]==1) {
  2351.             $out_w = $size[0];
  2352.             $out_h = $size[1];
  2353.     } //what was this for again? */
  2354.   } else {
  2355.     $out_w = $size[0];
  2356.     $out_h = $size[1];
  2357.   }
  2358.   // the thumbnail is created
  2359.   if(function_exists("ImageCreateTrueColor")&&get_gd_ver()=="2"){
  2360.     $im_out = ImageCreateTrueColor($out_w, $out_h);
  2361.   }else{$im_out = ImageCreate($out_w, $out_h);}
  2362.   // copy resized original
  2363.   ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $out_w, $out_h, $size[0], $size[1]);
  2364.   // thumbnail saved
  2365.   ImageJPEG($im_out, $outpath ,60);
  2366.   //chmod($thumb_dir.$tim.'s.jpg',0666);
  2367.   // created image is destroyed
  2368.   ImageDestroy($im_in);
  2369.   ImageDestroy($im_out);
  2370.   if(isset($pdfjpeg)) { unlink($pdfjpeg); } // if PDF was thumbnailed delete the orig jpeg
  2371.   if($memory_limit_increased)
  2372.         ini_restore('memory_limit');
  2373.  
  2374.   return $outpath;
  2375. }
  2376.  
  2377. //check version of gd
  2378. function get_gd_ver(){
  2379.   if(function_exists("gd_info")){
  2380.     $gdver=gd_info();
  2381.     $phpinfo=$gdver["GD Version"];
  2382.   }else{ //earlier than php4.3.0
  2383.     ob_start();
  2384.     phpinfo(8);
  2385.     $phpinfo=ob_get_contents();
  2386.     ob_end_clean();
  2387.     $phpinfo=strip_tags($phpinfo);
  2388.     $phpinfo=stristr($phpinfo,"gd version");
  2389.     $phpinfo=stristr($phpinfo,"version");
  2390.   }
  2391.   $end=strpos($phpinfo,".");
  2392.   $phpinfo=substr($phpinfo,0,$end);
  2393.   $length = strlen($phpinfo)-1;
  2394.   $phpinfo=substr($phpinfo,$length);
  2395.   return $phpinfo;
  2396. }
  2397.  
  2398. //md5 calculation for earlier than php4.2.0
  2399. function md5_of_file($inFile) {
  2400.  if (file_exists($inFile)){
  2401.   if(function_exists('md5_file')){
  2402.     return md5_file($inFile);
  2403.   }else{
  2404.     $fd = fopen($inFile, 'r');
  2405.     $fileContents = fread($fd, filesize($inFile));
  2406.     fclose ($fd);
  2407.     return md5($fileContents);
  2408.   }
  2409.  }else{
  2410.   return false;
  2411. }}
  2412.  
  2413. /* text plastic surgery */
  2414. // you can call with skip_bidi=1 if cleaning a paragraph element (like $com)
  2415. function CleanStr($str,$skip_bidi=0){
  2416.   global $admin,$html;
  2417.   $str = trim($str);//blankspace removal
  2418.   if (get_magic_quotes_gpc()) {//magic quotes is deleted (?)
  2419.     $str = stripslashes($str);
  2420.   }
  2421.   if($admin!=ADMIN_PASS){
  2422.     $str = htmlspecialchars($str);
  2423.   }     elseif(( $admin==ADMIN_PASS)&&$html!=1) {
  2424.     $str = htmlspecialchars($str);
  2425.   }
  2426.   if($skip_bidi == 0) {
  2427.           // fix malformed bidirectional overrides - insert as many PDFs as RLOs
  2428.         //RLO
  2429.           $str .= str_repeat("\xE2\x80\xAC", substr_count($str, "\xE2\x80\xAE"/* U+202E */));
  2430.           $str .= str_repeat("&#8236;", substr_count($str, "&#8238;"));
  2431.           $str .= str_repeat("&#x202c;", substr_count($str, "&#x202e;"));
  2432.         //RLE
  2433.       $str .= str_repeat("\xE2\x80\xAC", substr_count($str, "\xE2\x80\xAB"/* U+202B */));
  2434.           $str .= str_repeat("&#8236;", substr_count($str, "&#8235;"));
  2435.           $str .= str_repeat("&#x202c;", substr_count($str, "&#x202b;"));
  2436.   }
  2437.   return str_replace(",", "&#44;", $str);//remove commas
  2438. }
  2439.  
  2440. //check for table existance
  2441. function table_exist($table){
  2442.   $result = mysql_board_call("show tables like '$table'");
  2443.   if(!$result){return 0;}
  2444.   $a = mysql_fetch_row($result);
  2445.   mysql_free_result($result);
  2446.   return $a;
  2447. }
  2448.  
  2449. function report() {
  2450.         require '/www/global/forms/report.php';
  2451.         require '/www/global/modes/report.php';
  2452.         if($_SERVER['REQUEST_METHOD'] == 'GET') {
  2453.                 if(!report_post_exists($_GET['no']))
  2454.                         fancydie('That post doesn\'t exist anymore.');
  2455.                 if(report_post_sticky($_GET['no']))
  2456.                         fancydie('Stop trying to report a sticky.');
  2457.                 report_check_ip(BOARD_DIR, $_GET['no']);
  2458.                 form_report(BOARD_DIR, $_GET['no']);
  2459.         }
  2460.         else {
  2461.                 report_check_ip(BOARD_DIR, $_POST['no']);
  2462.                 report_submit(BOARD_DIR, $_POST['no'], $_POST['cat']);
  2463.         }
  2464.         die('</body></html>');
  2465. }
  2466.  
  2467. /* user image deletion */
  2468. function usrdel($no,$pwd){
  2469.   global $path,$pwdc,$onlyimgdel;
  2470.   $host = $_SERVER["REMOTE_ADDR"];
  2471.   $delno = array();
  2472.   $delflag = FALSE;
  2473.   $rebuildindex = !(defined("STATIC_REBUILD") && STATIC_REBUILD);
  2474.   reset($_POST);
  2475.   while ($item = each($_POST)){
  2476.     if($item[1]=='delete'){array_push($delno,$item[0]);$delflag=TRUE;}
  2477.   }
  2478.   if(($pwd=="")&&($pwdc!="")) $pwd=$pwdc;
  2479.   $countdel=count($delno);
  2480.  
  2481.   $flag = FALSE;
  2482.   //mysql_board_call("LOCK TABLES ".SQLLOG." WRITE");
  2483.   $rebuild = array(); // keys are pages that need to be rebuilt (0 is index, of course)
  2484.   for($i = 0; $i<$countdel; $i++){
  2485.         $resto = delete_post($delno[$i], $pwd, $onlyimgdel, 0, 1, $countdel == 1); // only show error for user deletion, not multi
  2486.         if($resto)
  2487.                 $rebuild[$resto] = 1;
  2488.   }
  2489.   log_cache();
  2490.   //mysql_board_call("UNLOCK TABLES");  
  2491.   foreach($rebuild as $key=>$val) {
  2492.         updatelog($key, 1); // leaving the second parameter as 0 rebuilds the index each time!
  2493.   }
  2494.   if ($rebuildindex) updatelog(); // update the index page last
  2495. }
  2496.  
  2497. /*password validation */
  2498. function oldvalid($pass){
  2499.         error(S_WRONGPASS);
  2500.   /*if($pass && ($pass != ADMIN_PASS) ) {
  2501.         auto_ban_poster($name, 2, 1, 'failed the password check on imgboard manager mode', 'Trying to exploit administrative pages.');
  2502.         error(S_WRONGPASS);
  2503.   }*/
  2504.  
  2505.   head($dat,0);
  2506.   echo $dat;
  2507.   echo "[<a href=\"".PHP_SELF2."\">".S_RETURNS."</a>]\n";
  2508.   echo "[<a href=\"".PHP_SELF."\">".S_LOGUPD."</a>]\n";
  2509.   echo "<table width='100%'><tr><th bgcolor=#E08000>\n";
  2510.   echo "<font color=#FFFFFF>".S_MANAMODE."</font>\n";
  2511.   echo "</th></tr></table>\n";
  2512.   echo "<p><form action=\"".PHP_SELF."\" method=POST>\n";
  2513.   // Mana login form
  2514.   if(!$pass){
  2515.     echo "<center><input type=hidden name=admin value=post><input type=hidden name=mode value=admin>\n";
  2516.     echo "<input class=inputtext type=password name=pass size=8>";
  2517.     echo "<input type=submit value=\"".S_MANASUB."\"></form></center>\n";
  2518.     die("</body></html>");
  2519.   }
  2520. }
  2521.  
  2522. function rebuild($all=0) {
  2523.         header("Pragma: no-cache");
  2524.         echo "Rebuilding ";
  2525.         if($all) { echo "all"; } else { echo "missing"; }
  2526.         echo " replies and pages... <a href=\"".PHP_SELF2_ABS."\">Go back</a><br><br>\n";
  2527.         ob_end_flush();
  2528.         mysql_board_lock();
  2529.         $starttime = microtime(true);
  2530.         if(!$treeline=mysql_board_call("select no,resto from ".SQLLOG." where root>0 order by root desc")){echo S_SQLFAIL;}
  2531.         log_cache();
  2532.         mysql_board_unlock();
  2533.         echo "Writing...\n";
  2534.         if($all || !defined('CACHE_TTL')) {
  2535.                 while(list($no,$resto)=mysql_fetch_row($treeline)) {
  2536.                         if(!$resto) {
  2537.                                 updatelog($no,1);
  2538.                                 echo "No.$no created.<br>\n";
  2539.                         }
  2540.                 }
  2541.                 updatelog();
  2542.                 echo "Index pages created.<br>\n";
  2543.         }
  2544.         else {
  2545.                 $posts = rebuildqueue_take_all();
  2546.                 foreach($posts as $no) {
  2547.                         $deferred = ( updatelog($no,1) ? ' (deferred)' : '' );
  2548.                         if($no)
  2549.                                 echo "No.$no created.$deferred<br>\n";
  2550.                         else
  2551.                                 echo "Index pages created.$deferred<br>\n";
  2552.                 }
  2553.         }
  2554.         $totaltime = microtime(true) - $starttime;
  2555.         echo "<br>Time elapsed (lock excluded): $totaltime seconds","<br>Pages created.<br><br>\nRedirecting back to board.\n<META HTTP-EQUIV=\"refresh\" content=\"10;URL=".PHP_SELF2."\">";
  2556. }
  2557.  
  2558. /*-----------Main-------------*/
  2559. switch($mode){
  2560.   case 'regist':
  2561.     regist($name,$email,$sub,$com,'',$pwd,$upfile,$upfile_name,$resto,$age);
  2562.     break;
  2563.   case 'report':
  2564.     report();
  2565.     break;
  2566.   case 'admin':
  2567.     oldvalid($pass);
  2568.     if($admin=="post"){
  2569.       echo "</form>";
  2570.       form($post,$res,1);
  2571.       echo $post;
  2572.       die("</body></html>");
  2573.     }
  2574.     break;
  2575.   case 'rebuild':
  2576.       rebuild();
  2577.       break;
  2578.   case 'rebuildall':
  2579.       rebuild(1);
  2580.       break;
  2581.   case 'admindel':
  2582.       usrdel($no,$pwd);
  2583.       echo "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=admin.php\">";
  2584.       break;
  2585.   case 'nothing':
  2586.           break;
  2587.   case 'usrdel':
  2588.       usrdel($no,$pwd);
  2589.   default:
  2590.   if(JANITOR_BOARD == 1 && $mode == 'latest') {
  2591.         broomcloset_latest();
  2592.   }
  2593.   if(OEKAKI_BOARD == 1 && $mode == 'oe_finish') {
  2594.    require_once 'oekaki.php';
  2595.    oe_finish();
  2596.   }
  2597.   elseif(OEKAKI_BOARD == 1 && $mode == 'oe_paint') {
  2598.    require_once 'oekaki.php';
  2599.    oe_paint();
  2600.   }
  2601.   if($res){
  2602.       resredir($res);
  2603.       echo "<META HTTP-EQUIV=\"refresh\" content=\"10;URL=".PHP_SELF2_ABS."\">";
  2604.     }else{
  2605.         //mysql_board_call("LOCK TABLES ".SQLLOG." READ");
  2606.           echo "Updating index...\n";
  2607.         updatelog();
  2608.      //mysql_board_call("UNLOCK TABLES");
  2609.       echo "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=".PHP_SELF2_ABS."\">";
  2610.     }
  2611. }
  2612.  
  2613. ?>
clone this paste RAW Paste Data