function ModulePage() { global $PIO, $PTE; if (isset($_GET['action'])) { // 標籤雲 require './module/wordcloud.class.php'; $pte_vals = array('{$TITLE}' => TITLE, '{$RESTO}' => ''); $dat = $PTE->ParseBlock('HEADER', $pte_vals); $dat .= '<style type="text/css"> .word { padding: 4px 4px 4px 4px; letter-spacing: 3px; text-decoration: none; font-weight: normal; } .size9 { color: #000 !important; font-size: 200%; } .size8 { color: #111 !important; font-size: 170%; } .size7 { color: #222 !important; font-size: 150%; } .size6 { color: #333 !important; font-size: 120%; } .size5 { color: #444 !important; font-size: 110%; } .size4 { color: #555 !important; font-size: 100%; } .size3 { color: #666 !important; font-size: 90%; } .size2 { color: #777 !important; font-size: 80%; } .size1 { color: #888 !important; font-size: 70%; } .size0 { color: #999 !important; font-size: 60%; } </style> </head> <body id="main">'; $p = $PIO->fetchPosts($PIO->fetchPostList()); $cloud = new wordCloud(); foreach ($p as $pp) { if ($pp['category']) { $pp['category'] = substr(str_replace(array(',', ','), ' ', $pp['category']), 1, -1); $cloud->addString($pp['category']); } } $myCloud = $cloud->showCloud('array'); if (is_array($myCloud)) { foreach ($myCloud as $key => $value) { $dat .= '<a href="./pixmicat.php?mode=category&c=' . urlencode($value['word']) . '" class="word size' . $value['range'] . '">' . $value['word'] . '</a>' . "\n"; } } echo $dat . "</body></html>"; return; } if (!isset($_GET['no'])) { die('[Error] not enough parameter.'); } if (!isset($_POST['tag'])) { $post = $PIO->fetchPosts($_GET['no']); if (!count($post)) { die('[Error] Post does not exist.'); } $pte_vals = array('{$TITLE}' => TITLE, '{$RESTO}' => ''); $dat = $PTE->ParseBlock('HEADER', $pte_vals); $dat .= '</head><body id="main">'; $dat .= '<form action="' . $this->mypage . '&no=' . $_GET['no'] . '" method="POST">Tag: <input type="text" name="tag" value="' . htmlentities(substr(str_replace(',', ',', $post[0]['category']), 1, -1), ENT_QUOTES, 'UTF-8') . '" size="28" /><input type="submit" name="submit" value="Tag!" /></form>'; echo $dat . "</body></html>"; } else { $Tag = CleanStr($_POST['tag']); if ($_SERVER['REQUEST_METHOD'] != 'POST') { error(_T('regist_notpost')); } // 非正規POST方式 $post = $PIO->fetchPosts($_GET['no']); $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no']; $threads = array_flip($PIO->fetchThreadList()); $threadPage = floor($threads[$parentNo] / PAGE_DEF); if (!count($post)) { die('[Error] Post does not exist.'); } if (USE_CATEGORY && $Tag) { // 修整標籤樣式 $ss = method_exists($PIO, '_replaceComma') ? ',' : ','; // Dirty implement $category = explode(',', $Tag); // 把標籤拆成陣列 $category = $ss . implode($ss, array_map('trim', $category)) . $ss; // 去空白再合併為單一字串 (左右含,便可以直接以,XX,形式搜尋) } else { $category = ''; } $PIO->updatePost($_GET['no'], array('category' => $category)); $PIO->dbCommit(); if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) { updatelog(0, $threadPage, true); } // 僅更新討論串出現那頁 deleteCache(array($parentNo)); // 刪除討論串舊快取 if (isset($_POST['ajaxmode'])) { echo $Tag; } else { header('HTTP/1.1 302 Moved Temporarily'); header('Location: ' . fullURL() . PHP_SELF2 . '?' . time()); } } }
function regist() { global $BAD_STRING, $BAD_FILEMD5, $BAD_IPADDR, $LIMIT_SENSOR, $THUMB_SETTING; $PIO = PMCLibrary::getPIOInstance(); $FileIO = PMCLibrary::getFileIOInstance(); $PMS = PMCLibrary::getPMSInstance(); $dest = ''; $mes = ''; $up_incomplete = 0; $is_admin = false; $delta_totalsize = 0; // 總檔案大小的更動值 if ($_SERVER['REQUEST_METHOD'] != 'POST') { error(_T('regist_notpost')); } // 非正規POST方式 // 欄位陷阱 $FTname = isset($_POST['name']) ? $_POST['name'] : ''; $FTemail = isset($_POST['email']) ? $_POST['email'] : ''; $FTsub = isset($_POST['sub']) ? $_POST['sub'] : ''; $FTcom = isset($_POST['com']) ? $_POST['com'] : ''; $FTreply = isset($_POST['reply']) ? $_POST['reply'] : ''; if ($FTname != 'spammer' || $FTemail != '*****@*****.**' || $FTsub != 'DO NOT FIX THIS' || $FTcom != 'EID OG SMAPS' || $FTreply != '') { error(_T('regist_nospam')); } $name = isset($_POST[FT_NAME]) ? CleanStr($_POST[FT_NAME]) : ''; $email = isset($_POST[FT_EMAIL]) ? CleanStr($_POST[FT_EMAIL]) : ''; $sub = isset($_POST[FT_SUBJECT]) ? CleanStr($_POST[FT_SUBJECT]) : ''; $com = isset($_POST[FT_COMMENT]) ? $_POST[FT_COMMENT] : ''; $pwd = isset($_POST['pwd']) ? $_POST['pwd'] : ''; $category = isset($_POST['category']) ? CleanStr($_POST['category']) : ''; $resto = isset($_POST['resto']) ? intval($_POST['resto']) : 0; $upfile = isset($_FILES['upfile']['tmp_name']) ? $_FILES['upfile']['tmp_name'] : ''; $upfile_path = isset($_POST['upfile_path']) ? $_POST['upfile_path'] : ''; $upfile_name = isset($_FILES['upfile']['name']) ? $_FILES['upfile']['name'] : false; $upfile_status = isset($_FILES['upfile']['error']) ? $_FILES['upfile']['error'] : 4; $pwdc = isset($_COOKIE['pwdc']) ? $_COOKIE['pwdc'] : ''; $ip = getREMOTE_ADDR(); $host = gethostbyaddr($ip); $PMS->useModuleMethods('RegistBegin', array(&$name, &$email, &$sub, &$com, array('file' => &$upfile, 'path' => &$upfile_path, 'name' => &$upfile_name, 'status' => &$upfile_status), array('ip' => $ip, 'host' => $host), $resto)); // "RegistBegin" Hook Point // 封鎖:IP/Hostname/DNSBL 檢查機能 $baninfo = ''; if (BanIPHostDNSBLCheck($ip, $host, $baninfo)) { error(_T('regist_ipfiltered', $baninfo)); } // 封鎖:限制出現之文字 foreach ($BAD_STRING as $value) { if (strpos($com, $value) !== false || strpos($sub, $value) !== false || strpos($name, $value) !== false || strpos($email, $value) !== false) { error(_T('regist_wordfiltered')); } } // 檢查是否輸入櫻花日文假名 foreach (array($name, $email, $sub, $com) as $anti) { if (anti_sakura($anti)) { error(_T('regist_sakuradetected')); } } // 時間 $time = time(); $tim = $time . substr(microtime(), 2, 3); // 判斷上傳狀態 switch ($upfile_status) { case 1: error(_T('regist_upload_exceedphp')); break; case 2: error(_T('regist_upload_exceedcustom')); break; case 3: error(_T('regist_upload_incompelete')); break; case 6: error(_T('regist_upload_direrror')); break; case 4: // 無上傳 if (!$resto && !isset($_POST['noimg'])) { error(_T('regist_upload_noimg')); } break; case 0: // 上傳正常 // 上傳正常 default: } // 如果有上傳檔案則處理附加圖檔 if ($upfile && (@is_uploaded_file($upfile) || @is_file($upfile))) { // 一‧先儲存檔案 $dest = STORAGE_PATH . $tim . '.tmp'; @move_uploaded_file($upfile, $dest) or @copy($upfile, $dest); @chmod($dest, 0666); if (!is_file($dest)) { error(_T('regist_upload_filenotfound'), $dest); } // 二‧判斷上傳附加圖檔途中是否有中斷 $upsizeTTL = $_SERVER['CONTENT_LENGTH']; if (isset($_FILES['upfile'])) { // 有傳輸資料才需要計算,避免作白工 $upsizeHDR = 0; // 檔案路徑:IE附完整路徑,故得從隱藏表單取得 $tmp_upfile_path = $upfile_name; if ($upfile_path) { $tmp_upfile_path = get_magic_quotes_gpc() ? stripslashes($upfile_path) : $upfile_path; } list(, $boundary) = explode('=', $_SERVER['CONTENT_TYPE']); foreach ($_POST as $header => $value) { // 表單欄位傳送資料 $upsizeHDR += strlen('--' . $boundary . "\r\n"); $upsizeHDR += strlen('Content-Disposition: form-data; name="' . $header . '"' . "\r\n\r\n" . (get_magic_quotes_gpc() ? stripslashes($value) : $value) . "\r\n"); } // 附加圖檔欄位傳送資料 $upsizeHDR += strlen('--' . $boundary . "\r\n"); $upsizeHDR += strlen('Content-Disposition: form-data; name="upfile"; filename="' . $tmp_upfile_path . "\"\r\n" . 'Content-Type: ' . $_FILES['upfile']['type'] . "\r\n\r\n"); $upsizeHDR += strlen("\r\n--" . $boundary . "--\r\n"); $upsizeHDR += $_FILES['upfile']['size']; // 傳送附加圖檔資料量 // 上傳位元組差值超過 HTTP_UPLOAD_DIFF:上傳附加圖檔不完全 if ($upsizeTTL - $upsizeHDR > HTTP_UPLOAD_DIFF) { if (KILL_INCOMPLETE_UPLOAD) { unlink($dest); die(_T('regist_upload_killincomp')); // 給瀏覽器的提示,假如使用者還看的到的話才不會納悶 } else { $up_incomplete = 1; } } } // 三‧檢查是否為可接受的檔案 $size = @getimagesize($dest); if (!is_array($size)) { error(_T('regist_upload_notimage'), $dest); } // $size不為陣列就不是圖檔 $imgsize = @filesize($dest); // 檔案大小 $imgsize = $imgsize >= 1024 ? (int) ($imgsize / 1024) . ' KB' : $imgsize . ' B'; // KB和B的判別 switch ($size[2]) { // 判斷上傳附加圖檔之格式 case 1: $ext = ".gif"; break; case 2: $ext = ".jpg"; break; case 3: $ext = ".png"; break; case 4: $ext = ".swf"; break; case 5: $ext = ".psd"; break; case 6: $ext = ".bmp"; break; case 13: $ext = ".swf"; break; default: $ext = ".xxx"; error(_T('regist_upload_notsupport'), $dest); } $allow_exts = explode('|', strtolower(ALLOW_UPLOAD_EXT)); // 接受之附加圖檔副檔名 if (array_search(substr($ext, 1), $allow_exts) === false) { error(_T('regist_upload_notsupport'), $dest); } // 並無在接受副檔名之列 // 封鎖設定:限制上傳附加圖檔之MD5檢查碼 $md5chksum = md5_file($dest); // 檔案MD5 if (array_search($md5chksum, $BAD_FILEMD5) !== FALSE) { error(_T('regist_upload_blocked'), $dest); } // 在封鎖設定內則阻擋 // 四‧計算附加圖檔圖檔縮圖顯示尺寸 $W = $imgW = $size[0]; $H = $imgH = $size[1]; $MAXW = $resto ? MAX_RW : MAX_W; $MAXH = $resto ? MAX_RH : MAX_H; if ($W > $MAXW || $H > $MAXH) { $W2 = $MAXW / $W; $H2 = $MAXH / $H; $key = $W2 < $H2 ? $W2 : $H2; $W = ceil($W * $key); $H = ceil($H * $key); } $mes = _T('regist_uploaded', CleanStr($upfile_name)); } // 檢查表單欄位內容並修整 if (strlenUnicode($name) > INPUT_MAX) { error(_T('regist_nametoolong'), $dest); } if (strlenUnicode($email) > INPUT_MAX) { error(_T('regist_emailtoolong'), $dest); } if (strlenUnicode($sub) > INPUT_MAX) { error(_T('regist_topictoolong'), $dest); } if (strlenUnicode($resto) > INPUT_MAX) { error(_T('regist_longthreadnum'), $dest); } // E-mail / 標題修整 $email = str_replace("\r\n", '', $email); $sub = str_replace("\r\n", '', $sub); // 名稱修整 $name = str_replace(_T('trip_pre'), _T('trip_pre_fake'), $name); // 防止トリップ偽造 $name = str_replace(CAP_SUFFIX, _T('cap_char_fake'), $name); // 防止管理員キャップ偽造 $name = str_replace("\r\n", '', $name); $nameOri = $name; // 名稱 if (preg_match('/(.*?)[##](.*)/u', $name, $regs)) { // トリップ(Trip)機能 $name = $nameOri = $regs[1]; $cap = strtr($regs[2], array('&' => '&')); $salt = preg_replace('/[^\\.-z]/', '.', substr($cap . 'H.', 1, 2)); $salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef'); $name = $name . _T('trip_pre') . substr(crypt($cap, $salt), -10); } if (CAP_ENABLE && preg_match('/(.*?)[##](.*)/', $email, $aregs)) { // 管理員キャップ(Cap)機能 $acap_name = $nameOri; $acap_pwd = strtr($aregs[2], array('&' => '&')); if ($acap_name == CAP_NAME && $acap_pwd == CAP_PASS) { $name = '<span class="admin_cap">' . $name . CAP_SUFFIX . '</span>'; $is_admin = true; $email = $aregs[1]; // 去除 #xx 密碼 } } if (!$is_admin) { // 非管理員 $name = str_replace(_T('admin'), '"' . _T('admin') . '"', $name); $name = str_replace(_T('deletor'), '"' . _T('deletor') . '"', $name); } $name = str_replace('&' . _T('trip_pre'), '&' . _T('trip_pre'), $name); // 避免 &#xxxx; 後面被視為 Trip 留下 & 造成解析錯誤 // 內文修整 if (strlenUnicode($com) > COMM_MAX && !$is_admin) { error(_T('regist_commenttoolong'), $dest); } $com = CleanStr($com, $is_admin); // 引入$is_admin參數是因為當管理員キャップ啟動時,允許管理員依config設定是否使用HTML if (!$com && $upfile_status == 4) { error(_T('regist_withoutcomment')); } $com = str_replace(array("\r\n", "\r"), "\n", $com); $com = preg_replace("/\n(( | )*\n){3,}/", "\n", $com); if (!BR_CHECK || substr_count($com, "\n") < BR_CHECK) { $com = nl2br($com); } // 換行字元用<br />代替 $com = str_replace("\n", '', $com); // 若還有\n換行字元則取消換行 // 預設的內容 if (!$name || preg_match("/^[ | |]*\$/", $name)) { if (ALLOW_NONAME) { $name = DEFAULT_NONAME; } else { error(_T('regist_withoutname'), $dest); } } if (!$sub || preg_match("/^[ | |]*\$/", $sub)) { $sub = DEFAULT_NOTITLE; } if (!$com || preg_match("/^[ | |\t]*\$/", $com)) { $com = DEFAULT_NOCOMMENT; } // 修整標籤樣式 if ($category && USE_CATEGORY) { $category = explode(',', $category); // 把標籤拆成陣列 $category = ',' . implode(',', array_map('trim', $category)) . ','; // 去空白再合併為單一字串 (左右含,便可以直接以,XX,形式搜尋) } else { $category = ''; } if ($up_incomplete) { $com .= '<br /><br /><span class="warn_txt">' . _T('notice_incompletefile') . '</span>'; } // 上傳附加圖檔不完全的提示 // 密碼和時間的樣式 if ($pwd == '') { $pwd = $pwdc == '' ? substr(rand(), 0, 8) : $pwdc; } $pass = $pwd ? substr(md5($pwd), 2, 8) : '*'; // 生成真正儲存判斷用的密碼 $youbi = array(_T('sun'), _T('mon'), _T('tue'), _T('wed'), _T('thu'), _T('fri'), _T('sat')); $yd = $youbi[gmdate('w', $time + TIME_ZONE * 60 * 60)]; $now = gmdate('y/m/d', $time + TIME_ZONE * 60 * 60) . '(' . (string) $yd . ')' . gmdate('H:i', $time + TIME_ZONE * 60 * 60); if (DISP_ID) { // 顯示ID if ($email && DISP_ID == 1) { $now .= ' ID:???'; } else { $now .= ' ID:' . substr(crypt(md5(getREMOTE_ADDR() . IDSEED . gmdate('Ymd', $time + TIME_ZONE * 60 * 60)), 'id'), -8); } } // 連續投稿 / 相同附加圖檔檢查 $checkcount = 50; // 預設檢查50筆資料 $pwdc = substr(md5($pwdc), 2, 8); // Cookies密碼 if ($PIO->isSuccessivePost($checkcount, $com, $time, $pass, $pwdc, $host, $upfile_name)) { error(_T('regist_successivepost'), $dest); } // 連續投稿檢查 if ($dest) { if ($PIO->isDuplicateAttachment($checkcount, $md5chksum)) { error(_T('regist_duplicatefile'), $dest); } } // 相同附加圖檔檢查 if ($resto) { $ThreadExistsBefore = $PIO->isThread($resto); } // 舊文章刪除處理 if (PIOSensor::check('delete', $LIMIT_SENSOR)) { $delarr = PIOSensor::listee('delete', $LIMIT_SENSOR); if (count($delarr)) { deleteCache($delarr); $PMS->useModuleMethods('PostOnDeletion', array($delarr, 'recycle')); // "PostOnDeletion" Hook Point $files = $PIO->removePosts($delarr); if (count($files)) { $delta_totalsize -= $FileIO->deleteImage($files); } // 更新 delta 值 } } // 附加圖檔容量限制功能啟動:刪除過大檔 if (STORAGE_LIMIT && STORAGE_MAX > 0) { $tmp_total_size = $FileIO->getCurrentStorageSize(); // 取得目前附加圖檔使用量 if ($tmp_total_size > STORAGE_MAX) { $files = $PIO->delOldAttachments($tmp_total_size, STORAGE_MAX, false); $delta_totalsize -= $FileIO->deleteImage($files); } } // 判斷欲回應的文章是不是剛剛被刪掉了 if ($resto) { if ($ThreadExistsBefore) { // 欲回應的討論串是否存在 if (!$PIO->isThread($resto)) { // 被回應的討論串存在但已被刪 // 提前更新資料來源,此筆新增亦不紀錄 $PIO->dbCommit(); updatelog(); error(_T('regist_threaddeleted'), $dest); } else { // 檢查是否討論串被設為禁止回應 (順便取出原討論串的貼文時間) $post = $PIO->fetchPosts($resto); // [特殊] 取單篇文章內容,但是回傳的$post同樣靠[$i]切換文章! list($chkstatus, $chktime) = array($post[0]['status'], $post[0]['tim']); $chktime = substr($chktime, 0, -3); // 拿掉微秒 (後面三個字元) $flgh = $PIO->getPostStatus($chkstatus); if ($flgh->exists('TS')) { error(_T('regist_threadlocked'), $dest); } } } else { error(_T('thread_not_found'), $dest); } // 不存在 } // 計算某些欄位值 $no = $PIO->getLastPostNo('beforeCommit') + 1; isset($ext) ? 0 : ($ext = ''); isset($imgW) ? 0 : ($imgW = 0); isset($imgH) ? 0 : ($imgH = 0); isset($imgsize) ? 0 : ($imgsize = ''); isset($W) ? 0 : ($W = 0); isset($H) ? 0 : ($H = 0); isset($md5chksum) ? 0 : ($md5chksum = ''); $age = false; $status = ''; if ($resto) { if (!stristr($email, 'sage') && ($PIO->postCount($resto) <= MAX_RES || MAX_RES == 0)) { if (!MAX_AGE_TIME || $time - $chktime < MAX_AGE_TIME * 60 * 60) { $age = true; } // 討論串並無過期,推文 } } $PMS->useModuleMethods('RegistBeforeCommit', array(&$name, &$email, &$sub, &$com, &$category, &$age, $dest, $resto, array($W, $H, $imgW, $imgH), &$status)); // "RegistBeforeCommit" Hook Point // 正式寫入儲存 $PIO->addPost($no, $resto, $md5chksum, $category, $tim, $ext, $imgW, $imgH, $imgsize, $W, $H, $pass, $now, $name, $email, $sub, $com, $host, $age, $status); $PIO->dbCommit(); $lastno = $PIO->getLastPostNo('afterCommit'); // 取得此新文章編號 $PMS->useModuleMethods('RegistAfterCommit', array($lastno, $resto, $name, $email, $sub, $com)); // "RegistAfterCommit" Hook Point // Cookies儲存:密碼與E-mail部分,期限是一週 setcookie('pwdc', $pwd, time() + 7 * 24 * 3600); setcookie('emailc', $email, time() + 7 * 24 * 3600); if ($dest && is_file($dest)) { $destFile = IMG_DIR . $tim . $ext; // 圖檔儲存位置 $thumbFile = THUMB_DIR . $tim . 's.' . $THUMB_SETTING['Format']; // 預覽圖儲存位置 if (USE_THUMB !== 0) { // 生成預覽圖 $thumbType = USE_THUMB; if (USE_THUMB == 1) { $thumbType = 'gd'; } // 與舊設定相容 require ROOTPATH . 'lib/thumb/thumb.' . $thumbType . '.php'; $thObj = new ThumbWrapper($dest, $imgW, $imgH); $thObj->setThumbnailConfig($W, $H, $THUMB_SETTING); $thObj->makeThumbnailtoFile($thumbFile); @chmod($thumbFile, 0666); unset($thObj); } rename($dest, $destFile); if (file_exists($destFile)) { $FileIO->uploadImage($tim . $ext, $destFile, filesize($destFile)); $delta_totalsize += filesize($destFile); } if (file_exists($thumbFile)) { $FileIO->uploadImage($tim . 's.' . $THUMB_SETTING['Format'], $thumbFile, filesize($thumbFile)); $delta_totalsize += filesize($thumbFile); } } // delta != 0 表示總檔案大小有更動,須更新快取 if ($delta_totalsize != 0) { $FileIO->updateStorageSize($delta_totalsize); } updatelog(); // 引導使用者至新頁面 $RedirURL = PHP_SELF2 . '?' . $tim; // 定義儲存資料後轉址目標 if (isset($_POST['up_series'])) { // 勾選連貼機能 if ($resto) { $RedirURL = PHP_SELF . '?res=' . $resto . '&upseries=1'; } else { $RedirURL = PHP_SELF . '?res=' . $lastno . '&upseries=1'; // 新增主題後繼續轉到此主題下 } } $RedirforJS = strtr($RedirURL, array("&" => "&")); // JavaScript用轉址目標 echo <<<_REDIR_ <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="utf-8"> <title></title> <meta http-equiv="Refresh" content="1;URL={$RedirURL}" /> <script type="text/javascript"> // Redirection (use JS) // <![CDATA[ function redir(){ \tlocation.href = "{$RedirforJS}"; } setTimeout("redir()", 1000); // ]]> </script> </head> <body> <div> _REDIR_; echo _T('regist_redirect', $mes, $RedirURL) . '</div> </body> </html>'; }
function ModulePage() { global $PMS; if (!adminAuthenticate('check')) { die('[Error] Access Denied.'); } // 進行新增、刪除等動作 if (isset($_POST['operate'])) { $op = $_POST['operate']; // 新增資料 $ndata = isset($_POST['newdata']) ? get_magic_quotes_gpc() ? stripslashes($_POST['newdata']) : $_POST['newdata'] : ''; // 資料內容 $nperiod = isset($_POST['newperiod']) ? intval($_POST['newperiod']) : 0; // 封鎖天數 $ndesc = isset($_POST['newdesc']) ? CleanStr($_POST['newdesc']) : ''; // 註解 if ($ndata && ($op == 'badstr' || $op == 'badua') && ($nperiod || isset($_POST['plaintext']))) { $ndata = preg_quote($ndata, '`'); } // plain text, not regex // 刪除資料 $del = isset($_POST['del']) ? $_POST['del'] : null; $newline = ''; $ismodified = $op != 'imghash' && ($ndata != '' || $del != null); // 是否需要修改檔案內容 if ($ismodified) { switch ($op) { case 'ip': $file = $this->ipfile; if ($ndata != '') { $newline = $ndata . "\t" . $ndesc . "\t" . time() . "\t" . $nperiod . "\n"; } break; case 'img': $file = $this->imgfile; if ($ndata != '') { $newline = $ndata . "\t" . $ndesc . "\n"; } break; case 'badstr': $file = $this->badstrfile; if ($ndata != '') { $newline = $ndata . "\t" . $ndesc . "\n"; } break; case 'badua': $file = $this->baduafile; if ($ndata != '') { $newline = $ndata . "\t" . $ndesc . "\n"; } break; } $this->_arrangeRecord($file, $del, $newline); // 同步進行刪除及更新 } if ($op == 'imghash') { foreach ($del as $file) { if (file_exists($this->imghash_imgdir . $file)) { unlink($this->imghash_imgdir . $file); } if (file_exists($this->imghash_hashdir . $file . '.imghash')) { unlink($this->imghash_hashdir . $file . '.imghash'); } } } if (isset($_POST['ajax'])) { // AJAX 要求在此即停止,一般要求則繼續印出頁面 $extend = $op == 'ip' ? '<td>' . date('Y/m/d H:m:s', time()) . " ({$nperiod})</td>" : ''; // IP黑名單資訊比圖檔多 echo '<tr><td>' . htmlspecialchars($ndata) . '</td><td>' . $ndesc . '</td>' . $extend . '<td><input type="checkbox" name="del[]" value="#NO#" /></td></tr>'; return; } } $dat = ''; $PMS->hookModuleMethod('Head', array(&$this, '_hookHeadCSS')); head($dat); $dat .= '<div class="bar_admin">封鎖黑名單管理</div> <div id="content"> <form action="' . $this->mypage . '" method="post"> <div id="ipconfig"><input type="hidden" name="operate" value="ip" /> IP 黑名單<br /> Pattern: <input type="text" name="newdata" size="30" /> Period: <input type="text" name="newperiod" size="5" value="0" />Day(s) Desc: <input type="text" name="newdesc" size="30" /> <input type="submit" value="新增" onclick="return add(this.form);" /><br /> <div class="dos_list_short"> <table border="0" width="100%"> <tr><td>Pattern</td><td>Description</td><td>Add Date (Period)</td><td>Delete</td></tr> '; foreach ($this->_parseBlackListFile($this->ipfile) as $i => $l) { $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td>' . '<td>' . (isset($l[2]) ? date('Y/m/d H:m:s', $l[2]) : '-') . (isset($l[3]) ? ' (' . $l[3] . ')' : ' (0)') . '</td>' . '<td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n"; } $dat .= '</table> </div> <input type="submit" value="刪除" /> </div> </form> <form action="' . $this->mypage . '" method="post"> <div id="imgconfig"><input type="hidden" name="operate" value="img" /> 圖檔 MD5 黑名單<br /> MD5: <input type="text" name="newdata" size="30" /> Desc: <input type="text" name="newdesc" size="30" /> <input type="hidden" name="newperiod" value="0" /> <input type="submit" value="新增" onclick="return add(this.form);" /><br /> <div class="dos_list_short"> <table border="0" width="100%"> <tr><td>MD5</td><td>Description</td><td>Delete</td></tr> '; foreach ($this->_parseBlackListFile($this->imgfile) as $i => $l) { $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n"; } $dat .= '</table> </div> <input type="submit" value="刪除" /> </div> </form>'; if ($this->use_imghash) { $dat .= '<form action="' . $this->mypage . '" method="post"> <div id="imgconfig"><input type="hidden" name="operate" value="imghash" /> 圖檔 imghash 黑名單<br /> <div class="dos_list_short"> <table border="0" width="100%"> <tr><td>File</td><td>Preview</td><td>Delete</td></tr> '; $pfolder = opendir($this->imghash_imgdir); //Folder $pnamebase = array(); while ($file = readdir($pfolder)) { if (is_file($this->imghash_imgdir . $file)) { $dat .= '<tr><td>' . $file . '</td><td><a href="' . $this->imghash_imgdir . $file . '" target="_blank">■</a></td><td><input type="checkbox" name="del[]" value="' . $file . '" /></td></tr>' . "\n"; } } closedir($pfolder); $dat .= '</table> </div> <input type="submit" value="刪除" /> </div> </form>'; } $dat .= '<form action="' . $this->mypage . '" method="post"> <div id="imgconfig"><input type="hidden" name="operate" value="badstr" /> 文字黑名單<br /> 文字列(可用正規表達式,不需用 / 斜線): <input type="text" name="newdata" size="30" /> Desc: <input type="text" name="newdesc" size="30" /> <input type="hidden" name="newperiod" value="0" /> <label><input type="checkbox" name="plaintext" value="1" onchange="this.form.newperiod.value=this.checked?1:0" />純文字</label> <input type="submit" value="新增" onclick="return add(this.form);" /><br /> <div class="dos_list_short"> <table border="0" width="100%"> <tr><td>文字列</td><td>Description</td><td>Delete</td></tr> '; foreach ($this->_parseBlackListFile($this->badstrfile) as $i => $l) { $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n"; } $dat .= '</table> </div> <input type="submit" value="刪除" /> </div>'; $dat .= '<form action="' . $this->mypage . '" method="post"> <div id="uaconfig"><input type="hidden" name="operate" value="badua" /> User Agent黑名單<br /> 文字列(可用正規表達式,不需用 / 斜線): <input type="text" name="newdata" size="30" /> Desc: <input type="text" name="newdesc" size="30" /> <input type="hidden" name="newperiod" value="0" /> <label><input type="checkbox" name="plaintext" value="1" onchange="this.form.newperiod.value=this.checked?1:0" />純文字</label> <input type="submit" value="新增" onclick="return add(this.form);" /><br /> <div class="dos_list_short"> <table border="0" width="100%"> <tr><td>文字列</td><td>Description</td><td>Delete</td></tr> '; foreach ($this->_parseBlackListFile($this->baduafile) as $i => $l) { $dat .= '<tr><td>' . htmlspecialchars($l[0]) . '</td><td>' . (isset($l[1]) ? $l[1] : '') . '</td><td><input type="checkbox" name="del[]" value="' . $i . '" /></td></tr>' . "\n"; } $dat .= '</table> </div> <input type="submit" value="刪除" /> </div> </form> <hr /> <div id="help"><pre> 說明 Pattern: 可封鎖特定IP/Hostname發文。以使用者的IP位置或Host名稱進行判斷,所以兩種形式都可以使用。 例如 127.0.0.1 (IP) 和 localhost (Host) 代表的都是相同的電腦。 接受下列格式 - 完全相符 即是完全一模一樣的情況下才封鎖。 範例: 127.0.0.1 (127.0.0.1 O;127.0.0.2 X) localhost (localhost O;local X) - 萬用字元 可接受 * , ? 來代替一段未知的字元 (如同大家熟知的使用方式),這樣一來可匹配的情況將增加。 範例: 192.168.0.* (192.168.0.3 O;192.168.1.3 X) local* (localhost O;remotehost X) - 正規表達式 使用Regular Expression來進行匹配,可作出更多樣、更適合的條件。注意使用時需要使用 / 斜線將表達式括住。 範例: /127\\.0\\.0\\.[0-9]{2}/ (127.0.0.28 O;127.0.0.1 X) /^.+\\.proxy\\.com$/ (gate1.proxy.com O;proxy2.com.tw X) - CIDR Notation 使用 Classless Addressing 這種更有彈性的方式切割子網路,其表示法稱作 CIDR,以一段IP位置加上Mask來劃分子網路 (注意此表示法僅能使用 IP)。 範例: 192.168.0.1/20 (192.168.7.243 O;192.168.18.144 X) Period: 設定封鎖期限,在過期時可以自動刪除解鎖,以天為單位。如果想永久封鎖 (系統不自動回收,需手動解鎖) 則將此值設為 0 (0 表示無期限)。</pre> </div> </div>'; foot($dat); echo $dat; }
function ModulePage() { global $PIO, $FileIO, $PMS, $language, $BAD_STRING, $BAD_FILEMD5, $BAD_IPADDR, $LIMIT_SENSOR; if (!isset($_GET['no'])) { die('[Error] not enough parameter.'); } if (!isset($_POST['mode'])) { // 顯示表單 if (!$this->shown_in_page && !adminAuthenticate('check')) { die('[Error] Access Denied.'); } $post = $PIO->fetchPosts($_GET['no']); if (!count($post)) { die('[Error] Post does not exist.'); } extract($post[0]); $PMS->loadModules('mod_bbcode'); //嘗試載入mod_bbcode if ($bbcode = $PMS->getModuleInstance('mod_bbcode')) { $bbcode->_html2bb($com); } $name = preg_replace('|<span.*?>(.*?)</span>|', '\\1', $name); $dat = ''; head($dat); $PMS->hookModuleMethod('PostInfo', array($this, '_EditPostInfo')); form($dat, $resto, false, $this->mypage . '&no=' . $_GET['no'], $name, $email, $sub, str_replace('<br />', "\n", $com), substr(str_replace(',', ',', $category), 1, -1), 'edit'); foot($dat); echo $dat; } else { // 儲存 if ($_SERVER['REQUEST_METHOD'] != 'POST') { error(_T('regist_notpost')); } // 非正規POST方式 $post = $PIO->fetchPosts($_GET['no']); $newValues = array(); if (!count($post)) { die('[Error] Post does not exist.'); } $name = isset($_POST[FT_NAME]) ? $_POST[FT_NAME] : ''; $email = isset($_POST[FT_EMAIL]) ? $_POST[FT_EMAIL] : ''; $sub = isset($_POST[FT_SUBJECT]) ? $_POST[FT_SUBJECT] : ''; $com = isset($_POST[FT_COMMENT]) ? $_POST[FT_COMMENT] : ''; $pwd = isset($_POST['pwd']) ? $_POST['pwd'] : ''; $category = isset($_POST['category']) ? $_POST['category'] : ''; $resto = isset($_POST['resto']) ? $_POST['resto'] : 0; $upfile = ''; $upfile_path = ''; $upfile_name = false; $upfile_status = 4; $pwdc = isset($_COOKIE['pwdc']) ? $_COOKIE['pwdc'] : ''; if ($resto && !$PIO->isThread($resto)) { die('[Error] Thread was deleted.'); } $is_admin = $haveperm = $pwd == ADMIN_PASS || adminAuthenticate('check'); $PMS->useModuleMethods('Authenticate', array($pwd, 'useredit', &$haveperm)); if ($pwd == '' && $pwdc != '') { $pwd = $pwdc; } $pwd_md5 = substr(md5($pwd), 2, 8); $host = gethostbyaddr(getREMOTE_ADDR()); if (!($pwd_md5 == $post[0]['pwd'] || $host == $post[0]['host'] || $haveperm)) { die('[Error] Access denied.'); } // 欄位陷阱 $FTname = isset($_POST['name']) ? $_POST['name'] : ''; $FTemail = isset($_POST['email']) ? $_POST['email'] : ''; $FTsub = isset($_POST['sub']) ? $_POST['sub'] : ''; $FTcom = isset($_POST['com']) ? $_POST['com'] : ''; $FTreply = isset($_POST['reply']) ? $_POST['reply'] : ''; if ($FTname != 'spammer' || $FTemail != '*****@*****.**' || $FTsub != 'DO NOT FIX THIS' || $FTcom != 'EID OG SMAPS' || $FTreply != '') { error(_T('regist_nospam')); } // 封鎖:IP/Hostname/DNSBL 檢查機能 $ip = getREMOTE_ADDR(); $host = gethostbyaddr($ip); $baninfo = ''; if (BanIPHostDNSBLCheck($ip, $host, $baninfo)) { error(_T('regist_ipfiltered', $baninfo)); } // 封鎖:限制出現之文字 foreach ($BAD_STRING as $value) { if (strpos($com, $value) !== false || strpos($sub, $value) !== false || strpos($name, $value) !== false || strpos($email, $value) !== false) { error(_T('regist_wordfiltered')); } } $PMS->useModuleMethods('RegistBegin', array(&$name, &$email, &$sub, &$com, array('file' => &$upfile, 'path' => &$upfile_path, 'name' => &$upfile_name, 'status' => &$upfile_status), array('ip' => $ip, 'host' => $host))); // "RegistBegin" Hook Point // 檢查是否輸入櫻花日文假名 $chkanti = array($name, $email, $sub, $com); foreach ($chkanti as $anti) { if (anti_sakura($anti)) { error(_T('regist_sakuradetected')); } } // 檢查表單欄位內容並修整 if (strlen($name) > 100) { error(_T('regist_nametoolong')); } if (strlen($email) > 100) { error(_T('regist_emailtoolong')); } if (strlen($sub) > 100) { error(_T('regist_topictoolong')); } if (strlen($resto) > 10) { error(_T('regist_longthreadnum')); } $email = CleanStr($email); $email = str_replace("\r\n", '', $email); $sub = CleanStr($sub); $sub = str_replace("\r\n", '', $sub); $resto = CleanStr($resto); $resto = str_replace("\r\n", '', $resto); // 名稱修整 $name = CleanStr($name); $name = str_replace(_T('trip_pre'), _T('trip_pre_fake'), $name); // 防止トリップ偽造 $name = str_replace(CAP_SUFFIX, _T('cap_char_fake'), $name); // 防止管理員キャップ偽造 $name = str_replace("\r\n", '', $name); $nameOri = $name; // 名稱 if (preg_match('/(.*?)[##](.*)/u', $name, $regs)) { // トリップ(Trip)機能 $name = $nameOri = $regs[1]; $cap = strtr($regs[2], array('&' => '&')); $salt = preg_replace('/[^\\.-z]/', '.', substr($cap . 'H.', 1, 2)); $salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef'); $name = $name . _T('trip_pre') . substr(crypt($cap, $salt), -10); } if (CAP_ENABLE && preg_match('/(.*?)[##](.*)/', $email, $aregs)) { // 管理員キャップ(Cap)機能 $acap_name = $nameOri; $acap_pwd = strtr($aregs[2], array('&' => '&')); if ($acap_name == CAP_NAME && $acap_pwd == CAP_PASS) { $name = '<span class="admin_cap">' . $name . CAP_SUFFIX . '</span>'; $is_admin = true; $email = $aregs[1]; // 去除 #xx 密碼 } } if (!$is_admin) { // 非管理員 $name = str_replace(_T('admin'), '"' . _T('admin') . '"', $name); $name = str_replace(_T('deletor'), '"' . _T('deletor') . '"', $name); } $name = str_replace('&◆', '&◆', $name); // 避免 &#xxxx; 後面被視為 Trip 留下 & 造成解析錯誤 // 內文修整 if (strlen($com) > COMM_MAX && !$is_admin) { error(_T('regist_commenttoolong')); } $com = CleanStr($com, $is_admin); // 引入$is_admin參數是因為當管理員キャップ啟動時,允許管理員依config設定是否使用HTML $com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com); $com = ereg_replace("\n(( | )*\n){3,}", "\n", $com); if (!BR_CHECK || substr_count($com, "\n") < BR_CHECK) { $com = nl2br($com); } // 換行字元用<br />代替 $com = str_replace("\n", '', $com); // 若還有\n換行字元則取消換行 if ($category && USE_CATEGORY) { // 修整標籤樣式 $category = explode(',', $category); // 把標籤拆成陣列 $category = ',' . implode(',', array_map('trim', $category)) . ','; // 去空白再合併為單一字串 (左右含,便可以直接以,XX,形式搜尋) } else { $category = ''; } $age = false; $dest = ''; $W = $post[0]['tw']; $H = $post[0]['th']; $imgW = $post[0]['imgw']; $imgH = $post[0]['imgh']; $status = $post[0]['status']; $PMS->useModuleMethods('RegistBeforeCommit', array(&$name, &$email, &$sub, &$com, &$category, &$age, $dest, $resto, array($W, $H, $imgW, $imgH), &$status)); // "RegistBeforeCommit" Hook Point if ($name != $post[0]['name'] && $_POST[FT_NAME]) { $newValues['name'] = $name; } if ($email != $post[0]['email'] && $_POST[FT_EMAIL]) { $newValues['email'] = $email; } if ($sub != $post[0]['sub'] && $_POST[FT_SUBJECT]) { $newValues['sub'] = $sub; } if ($com != $post[0]['com'] && $_POST[FT_COMMENT]) { $newValues['com'] = $com; } if ($category != $post[0]['category'] && $_POST['category']) { $newValues['category'] = $category; } $PIO->updatePost($_GET['no'], $newValues); $PIO->dbCommit(); $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no']; $threads = array_flip($PIO->fetchThreadList()); $threadPage = floor($threads[$parentNo] / PAGE_DEF); if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) { updatelog(0, $threadPage, true); } // 僅更新討論串出現那頁 deleteCache(array($parentNo)); // 刪除討論串舊快取 header('HTTP/1.1 302 Moved Temporarily'); header('Location: ' . fullURL() . PHP_SELF2 . '?' . time()); } }
function ModulePage() { global $PIO, $PTE; if (!isset($_GET['do'])) { // 沒有 "do" 指令,舊的 tag 連接 if (!isset($_GET['no'])) { die('[Error] not enough parameter.'); } if (!isset($_POST['tag'])) { $post = $PIO->fetchPosts($_GET['no']); if (!count($post)) { die('[Error] Post does not exist.'); } $pte_vals = array('{$TITLE}' => TITLE, '{$RESTO}' => ''); $dat = $PTE->ParseBlock('HEADER', $pte_vals); $dat .= '</head><body id="main">'; $dat .= '<form action="' . $this->mypage . '&no=' . $_GET['no'] . '" method="POST">Tag: <input type="text" name="tag" value="' . htmlentities(substr(str_replace(',', ',', $post[0]['category']), 1, -1), ENT_QUOTES, 'UTF-8') . '" size="28" /><input type="submit" name="submit" value="Tag!" /></form>'; echo $dat . "</body></html>"; } else { $Tag = CleanStr($_POST['tag']); if ($_SERVER['REQUEST_METHOD'] != 'POST') { error(_T('regist_notpost')); } // 非正規POST方式 $post = $PIO->fetchPosts($_GET['no']); $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no']; $threads = array_flip($PIO->fetchThreadList()); $threadPage = floor($threads[$parentNo] / PAGE_DEF); if (!count($post)) { die('[Error] Post does not exist.'); } $ss = method_exists($PIO, '_replaceComma') ? ',' : ','; // Dirty implement $category = explode(',', $Tag); // 把標籤拆成陣列 $category = $ss . implode($ss, array_map('trim', $category)) . $ss; // 去空白再合併為單一字串 (左右含,便可以直接以,XX,形式搜尋) $PIO->updatePost($_GET['no'], array('category' => $category)); $PIO->dbCommit(); if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) { updatelog(0, $threadPage, true); } // 僅更新討論串出現那頁 deleteCache(array($parentNo)); // 刪除討論串舊快取 if (isset($_POST['ajaxmode'])) { echo $Tag; } else { header('HTTP/1.1 302 Moved Temporarily'); header('Location: ' . fullURL() . PHP_SELF2 . '?' . time()); } } } else { // 有 "do" 指令,查看下一步 if ($_GET['do'] == "search") { // 搜尋符合標籤的主題 global $PTE, $PIO, $PMS, $FileIO, $language; $category = isset($_GET['c']) ? strtolower(strip_tags(trim($_GET['c']))) : ''; // 搜尋之類別標籤 if (!$category) { error(_T('category_nokeyword')); } $category_enc = urlencode($category); $category_md5 = md5($category); $page = isset($_GET['p']) ? @intval($_GET['p']) : 1; if ($page < 1) { $page = 1; } // 目前瀏覽頁數 $isrecache = isset($_GET['recache']); // 是否強制重新生成快取 // 利用Session快取類別標籤出現篇別以減少負擔 session_start(); // 啟動Session if (!isset($_SESSION['loglist_' . $category_md5]) || $isrecache) { $loglist = $PIO->searchCategory($category); $_SESSION['loglist_' . $category_md5] = serialize($loglist); } else { $loglist = unserialize($_SESSION['loglist_' . $category_md5]); } $loglist_count = count($loglist); if (!$loglist_count) { error(_T('category_notfound')); } $page_max = ceil($loglist_count / PAGE_DEF); if ($page > $page_max) { $page = $page_max; } // 總頁數 // 分割陣列取出適當範圍作分頁之用 $loglist_cut = array_slice($loglist, PAGE_DEF * ($page - 1), PAGE_DEF); // 取出特定範圍文章 $loglist_cut_count = count($loglist_cut); $dat = ''; head($dat); $links = '[<a href="' . PHP_SELF2 . '?' . time() . '">' . _T('return') . '</a>][<a href="' . PHP_SELF . '?mode=module&load=mod_tag&do=search&c=' . $category_enc . '&recache=1">' . _T('category_recache') . '</a>]'; $PMS->useModuleMethods('LinksAboveBar', array(&$links, 'category')); $dat .= "<div>{$links}</div>\n"; for ($i = 0; $i < $loglist_cut_count; $i++) { $tID = $loglist_cut[$i]; $tree_count = $PIO->postCount($tID) - 1; // 討論串回應個數 $RES_start = $tree_count - RE_DEF + 1; if ($RES_start < 1) { $RES_start = 1; } // 開始 $RES_amount = RE_DEF; // 取幾個 $hiddenReply = $RES_start - 1; // 被隱藏回應 // $RES_start, $RES_amount 拿去算新討論串結構 (分頁後, 部分回應隱藏) $tree = $PIO->fetchPostList($tID); // 整個討論串樹狀結構 $tree_cut = array_slice($tree, $RES_start, $RES_amount); array_unshift($tree_cut, $tID); // 取出特定範圍回應 $posts = $PIO->fetchPosts($tree_cut); // 取得文章架構內容 $dat .= arrangeThread($PTE, $tree, $tree_cut, $posts, $hiddenReply, 0, array(), array(), false, false, false); } $dat .= '<table border="1"><tr>'; if ($page > 1) { $dat .= '<td><form action="' . PHP_SELF . '?mode=module&load=mod_tag&do=search&c=' . $category_enc . '&p=' . ($page - 1) . '" method="post"><div><input type="submit" value="' . _T('prev_page') . '" /></div></form></td>'; } else { $dat .= '<td style="white-space: nowrap;">' . _T('first_page') . '</td>'; } $dat .= '<td>'; for ($i = 1; $i <= $page_max; $i++) { if ($i == $page) { $dat .= "[<b>" . $i . "</b>] "; } else { $dat .= '[<a href="' . PHP_SELF . '?mode=module&load=mod_tag&do=search&c=' . $category_enc . '&p=' . $i . '">' . $i . '</a>] '; } } $dat .= '</td>'; if ($page < $page_max) { $dat .= '<td><form action="' . PHP_SELF . '?mode=module&load=mod_tag&do=search&c=' . $category_enc . '&p=' . ($page + 1) . '" method="post"><div><input type="submit" value="' . _T('next_page') . '" /></div></form></td>'; } else { $dat .= '<td style="white-space: nowrap;">' . _T('last_page') . '</td>'; } $dat .= '</tr></table>' . "\n"; foot($dat); echo $dat; } else { if ($_GET['do'] == "cloud") { // 建立 tag cloud? // blah blah blah } else { // 不知道該如何處理的 "do" 指令 echo "スクリプトはTranslation Server Errorに免費の午餐を食べています!<br />"; echo "...你想表達什麼?"; } } } }
function reply($topic) { global $user; if (!$user) { message("Para poder responder un tema, necesitas identificarte.", "Responder tema"); } $topic_id = doquery("SELECT * FROM {{table}} WHERE topic_id={$topic}", "forum_topics", true); if (!$topic_id) { message("El tema no existe", "Nuevo tema", "forum.php"); } if (isset($_POST["post"])) { extract($_POST); /* Hacemos la comprobacion */ $postnumber = doquery("SELECT MAX(post_id) AS post_id FROM {{table}};", "forum_posts_text", true); $post_id = $postnumber["post_id"] + 1; $forum_id = $topic_id['forum_id']; //$topicnumber = doquery("SELECT MAX(topic_id) AS topic_id FROM {{table}};","forum_topics",true); $topic_id = $topic; //Convertimos el texto para que sea seguro durante la query... $content = CleanStr($content); //este seria el texto doquery("INSERT INTO {{table}} SET `post_id`={$post_id}, `bbcode_uid`='', `post_subject`='{$title}', `post_text`=\"{$content}\";", "forum_posts_text"); //este seria el index doquery("INSERT INTO {{table}} SET `post_id`={$post_id}, `topic_id`={$topic_id}, `forum_id`={$forum_id}, `poster_id`=" . $user['id'] . ", `post_time`=" . time() . ", `poster_ip`='be5577eb', `post_username`='', `enable_bbcode`=1, `enable_html`=0, `enable_smilies`=1, `enable_sig`=1, `post_edit_count`=0;", "forum_posts"); //actualiza el topic es el topico doquery("UPDATE {{table}} SET `topic_time`=" . time() . ", topic_replies=topic_replies+1, `topic_last_post_id`={$post_id} WHERE `topic_id`={$topic_id};", "forum_topics"); message("El nuevo tema se agrego correctamente. En unos instantes seras redirigido.", "Nuevo tema", "forum.php?t={$topic_id}#last"); } $topic_title = $topic_id["topic_title"]; //formulario form($page, $topic_title, "forum.php?new=reply&t={$topic}"); display($page, "Forum"); }
function ModulePage() { global $PMS, $PIO, $FileIO; if (!adminAuthenticate('check')) { die('[Error] Access Denied.'); } $content = ''; // POST if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') { // 刪除 $del = isset($_POST['del']) ? $_POST['del'] : null; if ($del != null) { $files = $PIO->removePosts($del); $delta_totalsize = 0; if (count($files)) { $delta_totalsize -= $FileIO->deleteImage($files); } if ($delta_totalsize != 0) { total_size($delta_totalsize); } foreach ($del as $n) { if ($oldCaches = glob('./cache/' . $n . '-*')) { foreach ($oldCaches as $o) { @unlink($o); } } } } // 對 host 作 search $filter = isset($_POST['filter']) ? CleanStr($_POST['filter']) : ''; if ($filter != '') { $res = $PIO->searchPost($filter, '`host`', 'AND'); foreach ($res as $p) { $no = $p['no']; $now = $p['now']; $host = $p['host']; $com = htmlspecialchars(str_cut(str_replace('<br />', ' ', $p['com']), 50)); $content .= <<<HERE <tr> \t<td><input type="checkbox" name="del[]" value="{$no}" /></td> \t<td>{$no}</td> \t<td>{$now}</td> \t<td>{$com}</td> \t<td>{$host}</td> </tr> HERE; } // 沒結果 if (count($res) == 0) { $content = '<tr><td rows="5">Not Found</td></tr>'; } } // AJAX 要求在此即停止,一般要求則繼續印出頁面 if (isset($_POST['ajax'])) { echo $content; return; } } // 顯示表單 $dat = ''; head($dat); $dat .= '<div class="bar_admin">搜尋 IP</div> <div id="content"> <form action="' . $this->SELF . '" method="post"> <div id="ipconfig"> Filter: <input type="text" name="filter" size="30" /> <input type="submit" value="搜尋" onclick="return search(this.form);" /><br /> <table border="0" width="100%"> <tr><th>Delete</th><th>No.</th><th>Date</th><th>Comment</th><th>Host</th></tr> ' . $content . ' </table> <input type="submit" value="刪除" /> </div> </form> <hr /> </div> <script type="text/javascript"> // <![CDATA[ function search(form){ var f = form.filter.value; $.post("' . str_replace('&', '&', $this->SELF) . '", {filter: f, ajax: true}, function(d){ $("table", form) // Remove all items except header .find("tr:gt(0)").remove() // Fill the results .end().append(d); }); return false; } // ]]> </script> '; foot($dat); echo $dat; }
function regist($name, $email, $sub, $com, $url, $pwd, $upfile, $upfile_name, $resto, $num) { global $path, $badstring, $badfile, $badip, $pwdc, $textonly, $auth; if ($pwd == PANEL_PASS) { $admin = $pwd; } if ($admin != PANEL_PASS || !valid()) { $admin = ''; } $mes = ""; if (valid('moderator')) { $moderator = 1; if (valid('admin')) { $moderator = 2; } if (valid('manager')) { $moderator = 3; } } if (isset($_POST['isSticky']) || isset($_POST['isLocked']) && valid('moderator')) { if (isset($_POST['isSticky'])) { $stickied = 1; } if (isset($_POST['isLocked'])) { $locked = 1; } } if (!$upfile && !$resto) { // allow textonly threads for moderators! if (valid('textonly')) { $textonly = 1; } } // time $time = time(); $tim = $time . substr(microtime(), 2, 3); // check closed $resto = (int) $resto; if ($resto) { if (!($cchk = mysql_call("select locked from " . SQLLOG . " where no=" . $resto))) { echo S_SQLFAIL; } list($locked) = mysql_fetch_row($cchk); if ($locked == 1 && !$admin) { error("You can't reply to this thread anymore.", $upfile); } mysql_free_result($cchk); } // upload processing $has_image = $upfile && file_exists($upfile); if ($has_image) { // check image limit if ($resto) { if (!($result = mysql_call("select COUNT(*) from " . SQLLOG . " where resto={$resto} and fsize!=0"))) { echo S_SQLFAIL; } $countimgres = mysql_result($result, 0, 0); if ($countimgres > MAX_IMGRES) { error("Max limit of " . MAX_IMGRES . " image replies has been reached.", $upfile); } mysql_free_result($result); } //upload processing $dest = tempnam(substr($path, 0, -1), "img"); //$dest = $path.$tim.'.tmp'; if (OEKAKI_BOARD == 1 && $_POST['oe_chk']) { rename($upfile, $dest); chmod($dest, 0644); if ($pchfile) { rename($pchfile, "{$dest}.pch"); } } else { move_uploaded_file($upfile, $dest); } clearstatcache(); // otherwise $dest looks like 0 bytes! $upfile_name = CleanStr($upfile_name); $fsize = filesize($dest); if (!is_file($dest)) { error(S_UPFAIL, $dest); } if (!$fsize || $fsize > MAX_KB * 1024) { error(S_TOOBIG, $dest); } // PDF processing if (ENABLE_PDF == 1 && strcasecmp('.pdf', substr($upfile_name, -4)) == 0) { $ext = '.pdf'; $W = $H = 1; $md5 = md5_of_file($dest); // run through ghostscript to check for validity if (pclose(popen("/usr/local/bin/gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=nullpage {$dest}", 'w'))) { error(S_UPFAIL, $dest); } } else { $size = getimagesize($dest); if (!is_array($size)) { error(S_NOREC, $dest); } $md5 = md5_of_file($dest); //chmod($dest,0666); $W = $size[0]; $H = $size[1]; switch ($size[2]) { case 1: $ext = ".gif"; break; case 2: $ext = ".jpg"; break; case 3: $ext = ".png"; break; case 4: $ext = ".swf"; error(S_UPFAIL, $dest); break; case 5: $ext = ".psd"; error(S_UPFAIL, $dest); break; case 6: $ext = ".bmp"; error(S_UPFAIL, $dest); break; case 7: $ext = ".tiff"; error(S_UPFAIL, $dest); break; case 8: $ext = ".tiff"; error(S_UPFAIL, $dest); break; case 9: $ext = ".jpc"; error(S_UPFAIL, $dest); break; case 10: $ext = ".jp2"; error(S_UPFAIL, $dest); break; case 11: $ext = ".jpx"; error(S_UPFAIL, $dest); break; case 13: $ext = ".swf"; error(S_UPFAIL, $dest); break; default: $ext = ".xxx"; error(S_UPFAIL, $dest); break; } if (GIF_ONLY == 1 && $size[2] != 1) { error(S_UPFAIL, $dest); } } // end processing -else // Picture reduction if (!$resto) { $maxw = MAX_W; $maxh = MAX_H; } else { $maxw = MAXR_W; $maxh = MAXR_H; } if (defined('MIN_W') && MIN_W > $W) { error(S_UPFAIL, $dest); } if (defined('MIN_H') && MIN_H > $H) { error(S_UPFAIL, $dest); } if (defined('MAX_DIMENSION')) { $maxdimension = MAX_DIMENSION; } else { $maxdimension = 5000; } if ($W > $maxdimension || $H > $maxdimension) { error(S_TOOBIGRES, $dest); } elseif ($W > $maxw || $H > $maxh) { $W2 = $maxw / $W; $H2 = $maxh / $H; $W2 < $H2 ? $key = $W2 : ($key = $H2); $W = ceil($W * $key); $H = ceil($H * $key); } $mes = $upfile_name . ' ' . S_UPGOOD; } if ($_FILES["upfile"]["error"] > 0) { if ($_FILES["upfile"]["error"] == UPLOAD_ERR_INI_SIZE) { error(S_TOOBIG, $dest); } if ($_FILES["upfile"]["error"] == UPLOAD_ERR_FORM_SIZE) { error(S_TOOBIG, $dest); } if ($_FILES["upfile"]["error"] == UPLOAD_ERR_PARTIAL) { error(S_UPFAIL, $dest); } if ($_FILES["upfile"]["error"] == UPLOAD_ERR_CANT_WRITE) { error(S_UPFAIL, $dest); } } if ($upfile_name && $_FILES["upfile"]["size"] == 0) { error(S_TOOBIGORNONE, $dest); } //The last result number $lastno = mysql_result(mysql_call("select max(no) from " . SQLLOG), 0, 0); // Number of log lines if (!($result = mysql_call("select no,ext,tim from " . SQLLOG . " where no<=" . ($lastno - LOG_MAX)))) { echo S_SQLFAIL; } else { while ($resrow = mysql_fetch_row($result)) { list($dno, $dext, $dtim) = $resrow; if (!mysql_query("delete from " . SQLLOG . " where no=" . $dno)) { echo S_SQLFAIL; } if ($dext) { if (is_file($path . $dtim . $dext)) { unlink($path . $dtim . $dext); } if (is_file(THUMB_DIR . $dtim . 's.jpg')) { unlink(THUMB_DIR . $dtim . 's.jpg'); } } } mysql_free_result($result); } $find = false; $resto = (int) $resto; if ($resto) { if (!($result = mysql_call("select * from " . SQLLOG . " where root>0 and no={$resto}"))) { echo S_SQLFAIL; } else { $find = mysql_fetch_row($result); mysql_free_result($result); } if (!$find) { error(S_NOTHREADERR, $dest); } } /* foreach ( $badstring as $value ) { if ( ereg( $value, $com ) || ereg( $value, $sub ) || ereg( $value, $name ) || ereg( $value, $email ) ) { error( S_STRREF, $dest ); } ; }*/ if ($_SERVER["REQUEST_METHOD"] != "POST") { error(S_UNJUST, $dest); } // Form content check if (!$name || ereg("^[ | |]*\$", $name)) { $name = ""; } if (!$com || ereg("^[ | |\t]*\$", $com)) { $com = ""; } if (!$sub || ereg("^[ | |]*\$", $sub)) { $sub = ""; } if (!$resto && !$textonly && !is_file($dest)) { error(S_NOPIC, $dest); } if (!$com && !is_file($dest)) { error(S_NOTEXT, $dest); } $name = ereg_replace(S_MANAGEMENT, "\"" . S_MANAGEMENT . "\"", $name); $name = ereg_replace(S_DELETION, "\"" . S_DELETION . "\"", $name); if (strlen($com) > S_POSTLENGTH) { error(S_TOOLONG, $dest); } if (strlen($name) > 100) { error(S_TOOLONG, $dest); } if (strlen($email) > 100) { error(S_TOOLONG, $dest); } if (strlen($sub) > 100) { error(S_TOOLONG, $dest); } if (strlen($resto) > 10) { error(S_UNUSUAL, $dest); } if (strlen($url) > 10) { error(S_UNUSUAL, $dest); } //host check $host = $_SERVER["REMOTE_ADDR"]; $badip = mysql_call("SELECT ip FROM " . SQLBANLOG . " WHERE ip = '{$host}' and banlength <> 0 "); if ($moderator) { $host = '###.###.###.###'; } // Don't store mod/admin ips $query = mysql_query("SELECT * FROM " . SQLLOG . " WHERE no=" . $resto); $result = mysql_fetch_assoc($query); if ($result["locked"] == '1') { error(S_THREADLOCKED, $dest); } //Check if user IP is in bans table if (mysql_num_rows($badip) == 0) { // Not Banned } else { //NOW YOU F****D UP error(S_BADHOST, $dest); } if (eregi("^mail", $host) || eregi("^ns", $host) || eregi("^dns", $host) || eregi("^ftp", $host) || eregi("^prox", $host) || eregi("^pc", $host) || eregi("^[^\\.]\\.[^\\.]\$", $host)) { $pxck = "on"; } if (eregi("ne\\.jp\$", $host) || eregi("ad\\.jp\$", $host) || eregi("bbtec\\.net\$", $host) || eregi("aol\\.com\$", $host) || eregi("uu\\.net\$", $host) || eregi("asahi-net\\.or\\.jp\$", $host) || eregi("rim\\.or\\.jp\$", $host)) { $pxck = "off"; } else { $pxck = "on"; } if ($pxck == "on" && PROXY_CHECK) { if (proxy_connect('80') == 1) { error(S_PROXY80, $dest); } elseif (proxy_connect('8080') == 1) { error(S_PROXY8080, $dest); } } // No, path, time, and url format srand((double) microtime() * 1000000); if ($pwd == "") { if ($pwdc == "") { $pwd = rand(); $pwd = substr($pwd, 0, 8); } else { $pwd = $pwdc; } } $c_pass = $pwd; $pass = $pwd ? substr(md5($pwd), 2, 8) : "*"; $youbi = array(S_SUN, S_MON, S_TUE, S_WED, S_THU, S_FRI, S_SAT); $yd = $youbi[date("w", $time)]; if (SHOW_SECONDS == 1) { $now = date("m/d/y", $time) . "(" . (string) $yd . ")" . date("H:i:s", $time); } else { $now = date("m/d/y", $time) . "(" . (string) $yd . ")" . date("H:i", $time); } if (DISP_ID) { if ($email && DISP_ID == 1) { $now .= " ID:???"; } else { $now .= " ID:" . substr(crypt(md5($_SERVER["REMOTE_ADDR"] . 'id' . date("Ymd", $time)), 'id'), +3); } } $c_name = $name; $c_email = $email; //Text plastic surgery (rorororor) $email = CleanStr($email); $email = ereg_replace("[\r\n]", "", $email); $sub = CleanStr($sub); $sub = ereg_replace("[\r\n]", "", $sub); $url = CleanStr($url); $url = ereg_replace("[\r\n]", "", $url); $resto = CleanStr($resto); $resto = ereg_replace("[\r\n]", "", $resto); $com = CleanStr($com, 1); if (SPOILERS == 1 && $spoiler) { $sub = "SPOILER<>{$sub}"; } // Standardize new character lines $com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com); //$com = preg_replace("/\A([0-9A-Za-z]{10})+\Z/", "!s8AAL8z!", $com); // Continuous lines $com = ereg_replace("\n(( | )*\n){3,}", "\n", $com); if (!$admin && substr_count($com, "\n") > MAX_LINES) { error("Error: Too many lines.", $dest); } $com = nl2br($com); //br is substituted before newline char $com = str_replace("\n", "", $com); //\n is erased // Continuous lines $com = ereg_replace("\n(( | )*\n){3,}", "\n", $com); if (!$admin && substr_count($com, "\n") > MAX_LINES) { error("Error: Too many lines.", $dest); } $name = ereg_replace("[\r\n]", "", $name); $names = iconv("UTF-8", "CP932//IGNORE", $name); // convert to Windows Japanese #kami //start new tripcode crap list($name) = explode("#", $name); $name = CleanStr($name); if (preg_match("/\\#+\$/", $names)) { $names = preg_replace("/\\#+\$/", "", $names); } if (preg_match("/\\#/", $names)) { $names = str_replace("&#", "&&", htmlspecialchars($names)); # otherwise HTML numeric entities screw up explode()! list($nametemp, $trip, $sectrip) = str_replace("&&", "&#", explode("#", $names, 3)); $names = $nametemp; $name .= "</span>"; if ($trip != "") { if (FORTUNE_TRIP == 1 && $trip == "fortune") { $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", "キタ━━━━━━(゚∀゚)━━━━━━ !!!!", "( ´_ゝ`)フーン ", "Good news will come to you by mail", "Hope you're insured", "Great things await", "Don't leave the house today."); $fortunenum = rand(0, sizeof($fortunes) - 1); $fortcol = "#" . sprintf("%02x%02x%02x", 127 + 127 * sin(2 * M_PI * $fortunenum / sizeof($fortunes)), 127 + 127 * sin(2 * M_PI * $fortunenum / sizeof($fortunes) + 2 / 3 * M_PI), 127 + 127 * sin(2 * M_PI * $fortunenum / sizeof($fortunes) + 4 / 3 * M_PI)); $com = "<font color={$fortcol}><b>Your fortune: " . $fortunes[$fortunenum] . "</b></font><br /><br />" . $com; $trip = ""; if ($sectrip == "") { if ($name == "</span>" && $sectrip == "") { $name = S_ANONAME; } else { $name = str_replace("</span>", "", $name); } } } else { if ($trip == "fortune") { //remove fortune even if FORTUNE_TRIP is off $trip = ""; if ($sectrip == "") { if ($name == "</span>" && $sectrip == "") { $name = S_ANONAME; } else { $name = str_replace("</span>", "", $name); } } } else { $salt = strtr(preg_replace("/[^\\.-z]/", ".", substr($trip . "H.", 1, 2)), ":;<=>?@[\\]^_`", "ABCDEFGabcdef"); $trip = substr(crypt($trip, $salt), -10); $name .= " <span class=\"postertrip\">!" . $trip; } } } if ($sectrip != "") { $salt = "LOLLOLOLOLOLOLOLOLOLOLOLOLOLOLOL"; #this is ONLY used if the host doesn't have openssl #I don't know a better way to get random data if (file_exists(SALTFILE)) { #already generated a key $salt = file_get_contents(SALTFILE); } else { system("openssl rand 448 > '" . SALTFILE . "'", $err); if ($err === 0) { chmod(SALTFILE, 0400); $salt = file_get_contents(SALTFILE); } } $sha = base64_encode(pack("H*", sha1($sectrip . $salt))); $sha = substr($sha, 0, 11); if ($trip == "") { $name .= " <span class=\"postertrip\" text-color=#117743>"; } $name .= "!!" . $sha; } } if ($email == 'noko') { $noko = 1; $email = ''; } else { if ($email == 'nokosage') { $noko = 1; $email = 'sage'; } } if ($moderator) { if ($moderator == 1 && isset($_POST['showCap'])) { $name = '<b><font color="770099">Anonymous ## Mod </font></b>'; } if ($moderator == 2 && isset($_POST['showCap'])) { $name = '<b><font color="FF101A">Anonymous ## Admin </font></b>'; } if ($moderator == 3 && isset($_POST['showCap'])) { $name = '<b><font color="2E2EFE">Anonymous ## Manager </font></b>'; } } if (!$name) { $name = S_ANONAME; } if (!$com) { $com = S_ANOTEXT; } if (!$sub) { $sub = S_ANOTITLE; } if (FORCED_ANON == 1) { $name = "</span>{$now}<span>"; $sub = ''; $now = ''; } $com = wordwrap2($com, 100, "<br />"); $com = preg_replace("!(^|>)(>[^<]*)!", "\\1<font class=\"unkfunc\">\\2</font>", $com); $is_sage = stripos($email, "sage") !== FALSE; $may_flood = valid('floodbypass'); if (!$may_flood) { if ($com) { // Check for duplicate comments $query = "select count(no)>0 from " . SQLLOG . " where com='" . mysql_real_escape_string($com) . "' " . "and host='" . mysql_real_escape_string($host) . "' " . "and time>" . ($time - RENZOKU_DUPE); $result = mysql_call($query); if (mysql_result($result, 0, 0)) { error(S_RENZOKU, $dest); } mysql_free_result($result); } if (!$has_image) { // Check for flood limit on replies $query = "select count(no)>0 from " . SQLLOG . " where time>" . ($time - RENZOKU) . " " . "and host='" . mysql_real_escape_string($host) . "' and resto>0"; $result = mysql_call($query); if (mysql_result($result, 0, 0)) { error(S_RENZOKU, $dest); } mysql_free_result($result); } if ($is_sage) { // Check flood limit on sage posts $query = "select count(no)>0 from " . SQLLOG . " where time>" . ($time - RENZOKU_SAGE) . " " . "and host='" . mysql_real_escape_string($host) . "' and resto>0 and permasage=1"; $result = mysql_call($query); if (mysql_result($result, 0, 0)) { error(S_RENZOKU, $dest); } mysql_free_result($result); } if (!$resto) { // Check flood limit on new threads $query = "select count(no)>0 from " . SQLLOG . " where time>" . ($time - RENZOKU3) . " " . "and host='" . mysql_real_escape_string($host) . "' and root>0"; //root>0 == non-sticky $result = mysql_call($query); if (mysql_result($result, 0, 0)) { error(S_RENZOKU3, $dest); } mysql_free_result($result); } } // Upload processing if ($has_image) { if (!$may_flood) { $query = "select count(no)>0 from " . SQLLOG . " where time>" . ($time - RENZOKU2) . " " . "and host='" . mysql_real_escape_string($host) . "' and resto>0"; $result = mysql_call($query); if (mysql_result($result, 0, 0)) { error(S_RENZOKU2, $dest); } mysql_free_result($result); } //Duplicate image check if (DUPE_CHECK) { $result = mysql_call("select no,resto from " . SQLLOG . " where md5='{$md5}'"); if (mysql_num_rows($result)) { list($dupeno, $duperesto) = mysql_fetch_row($result); if (!$duperesto) { $duperesto = $dupeno; } error('<a href="' . DATA_SERVER . BOARD_DIR . "/res/" . $duperesto . PHP_EXT . '#' . $dupeno . '">' . S_DUPE . '</a>', $dest); } mysql_free_result($result); } } $rootqu = $resto ? "0" : "now()"; if ($stickied) { $rootqu = '20270727070707'; } //Bump processing if ($resto) { //sage or age action $resline = mysql_call("select count(no) from " . SQLLOG . " where resto=" . $resto); $countres = mysql_result($resline, 0, 0); mysql_free_result($resline); $resline = mysql_call("select sticky,permasage from " . SQLLOG . " where no=" . $resto); list($sticky, $permasage) = mysql_fetch_row($resline); mysql_free_result($resline); if (stripos($email, 'sage') === FALSE && $countres < MAX_RES && $sticky != "1" && $permasage != "1" || $admin && $age && $sticky != "1") { $query = "update " . SQLLOG . " set root=now() where no={$resto}"; //age mysql_call($query); } } //Main insert $query = "insert into " . SQLLOG . " (now,name,email,sub,com,host,pwd,ext,w,h,tim,time,md5,fsize,fname,sticky,permasage,locked,root,resto) values (" . "'" . $now . "'," . "'" . mysql_real_escape_string($name) . "'," . "'" . mysql_real_escape_string($email) . "'," . "'" . mysql_real_escape_string($sub) . "'," . "'" . mysql_real_escape_string($com) . "'," . "'" . mysql_real_escape_string($host) . "'," . "'" . mysql_real_escape_string($pass) . "'," . "'" . $ext . "'," . (int) $W . "," . (int) $H . "," . "'" . $tim . "'," . (int) $time . "," . "'" . $md5 . "'," . (int) $fsize . "," . "'" . mysql_real_escape_string($upfile_name) . "'," . (int) $stickied . "," . (int) $permasage . "," . (int) $locked . "," . $rootqu . "," . (int) mysql_real_escape_string($resto) . ")"; if (!($result = mysql_call($query))) { echo S_SQLFAIL; } //post registration $cookie_domain = '.' . SITE_ROOT . ''; //Cookies setrawcookie("" . SITE_ROOT . "_name", rawurlencode($c_name), time() + ($c_name ? 7 * 24 * 3600 : -3600), '/', $cookie_domain); if ($c_email != "sage" && $c_email != "age") { setcookie("" . SITE_ROOT . "_email", $c_email, time() + ($c_email ? 7 * 24 * 3600 : -3600), '/', $cookie_domain); // 1 week cookie expiration } setcookie("" . SITE_ROOT . "_pass", $c_pass, time() + 7 * 24 * 3600, '/', $cookie_domain); // 1 week cookie expiration if (!$resto) { prune_old(); } // thumbnail if ($has_image) { rename($dest, $path . $tim . $ext); if (USE_THUMB) { $tn_name = thumb($path, $tim, $ext, $resto); if (!$tn_name && $ext != ".pdf") { error(S_UNUSUAL); } } } $static_rebuild = defined("STATIC_REBUILD") && STATIC_REBUILD == 1; //Finding the last entry number if (!($result = mysql_call("select max(no) from " . SQLLOG))) { echo S_SQLFAIL; } $hacky = mysql_fetch_array($result); $insertid = (int) $hacky[0]; mysql_free_result($result); $deferred = false; // update html if ($resto) { $deferred = updatelog($resto, $static_rebuild); } else { $deferred = updatelog($insertid, $static_rebuild); } if ($noko && !$resto) { $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $insertid . PHP_EXT; } else { if ($noko == 1) { $redirect = DATA_SERVER . BOARD_DIR . "/res/" . $resto . PHP_EXT . '#' . $insertid; } else { $redirect = PHP_SELF2_ABS; } } if ($deferred) { echo "<html><head><META HTTP-EQUIV=\"refresh\" content=\"2;URL={$redirect}\"></head>"; echo "<body>{$mes} " . S_SCRCHANGE . "<br>Your post may not appear immediately.<!-- thread:{$resto},no:{$insertid} --></body></html>"; } else { echo "<html><head><META HTTP-EQUIV=\"refresh\" content=\"1;URL={$redirect}\"></head>"; echo "<body>{$mes} " . S_SCRCHANGE . "<!-- thread:{$resto},no:{$insertid} --></body></html>"; } }
function regist($name, $email, $sub, $com, $url, $pwd, $upfile, $upfile_name, $resto) { global $path, $badstring, $badfile, $badip, $pwdc, $textonly; $dest = ""; $mes = ""; // 時間 $time = time(); $tim = $time . substr(microtime(), 2, 3); // アップロード処理 if ($upfile && file_exists($upfile)) { $dest = $path . $tim . '.tmp'; move_uploaded_file($upfile, $dest); //↑でエラーなら↓に変更 //copy($upfile, $dest); $upfile_name = CleanStr($upfile_name); if (!is_file($dest)) { error("アップロードに失敗しました<br>サーバがサポートしていない可能性があります", $dest); } $size = getimagesize($dest); if (!is_array($size)) { error("アップロードに失敗しました<br>画像ファイル以外は受け付けません", $dest); } $chk = md5_of_file($dest); foreach ($badfile as $value) { if (preg_match("^{$value}", $chk)) { error("アップロードに失敗しました<br>同じ画像がありました", $dest); //拒絶画像 } } chmod($dest, 0666); $W = $size[0]; $H = $size[1]; switch ($size[2]) { case 1: $ext = ".gif"; break; case 2: $ext = ".jpg"; break; case 3: $ext = ".png"; break; case 4: $ext = ".swf"; break; case 5: $ext = ".psd"; break; case 6: $ext = ".bmp"; break; case 13: $ext = ".swf"; break; default: $ext = ".xxx"; error("対応しないフォーマットです。", $dest); } // 画像表示縮小 if ($W > MAX_W || $H > MAX_H) { $W2 = MAX_W / $W; $H2 = MAX_H / $H; $W2 < $H2 ? $key = $W2 : ($key = $H2); $W = ceil($W * $key); $H = ceil($H * $key); } $mes = "画像 {$upfile_name} のアップロードが成功しました<br><br>"; } // foreach($badstring as $value){if(pregereg_replace_match($value,$com)||preg_match($value,$sub)||preg_match($value,$name)||preg_match($value,$email)){ // error("拒絶されました(str)",$dest);};} if ($_SERVER["REQUEST_METHOD"] != "POST") { error("不正な投稿をしないで下さい(post)", $dest); } // フォーム内容をチェック if (!$name || preg_match("^[ | |]*\$", $name)) { $name = ""; } if (!$com || preg_match("^[ | |\t]*\$", $com)) { $com = ""; } if (!$sub || preg_match("^[ | |]*\$", $sub)) { $sub = ""; } if (!$resto && !$textonly && !is_file($dest)) { error("画像がありません", $dest); } if (!$com && !is_file($dest)) { error("何か書いて下さい", $dest); } $name = preg_replace("管理", "\"管理\"", $name); $name = preg_replace("削除", "\"削除\"", $name); if (strlen($com) > 1000) { error("本文が長すぎますっ!", $dest); } if (strlen($name) > 100) { error("本文が長すぎますっ!", $dest); } if (strlen($email) > 100) { error("本文が長すぎますっ!", $dest); } if (strlen($sub) > 100) { error("本文が長すぎますっ!", $dest); } if (strlen($resto) > 10) { error("異常です", $dest); } if (strlen($url) > 10) { error("異常です", $dest); } //ホスト取得 $host = gethostbyaddr($_SERVER["REMOTE_ADDR"]); foreach ($badip as $value) { //拒絶host if (eregi("{$value}\$", $host)) { error("拒絶されました(host)", $dest); } } if (eregi("^mail", $host) || eregi("^ns", $host) || eregi("^dns", $host) || eregi("^ftp", $host) || eregi("^prox", $host) || eregi("^pc", $host) || eregi("^[^\\.]\\.[^\\.]\$", $host)) { $pxck = "on"; } if (eregi("ne\\.jp\$", $host) || eregi("ad\\.jp\$", $host) || eregi("bbtec\\.net\$", $host) || eregi("aol\\.com\$", $host) || eregi("uu\\.net\$", $host) || eregi("asahi-net\\.or\\.jp\$", $host) || eregi("rim\\.or\\.jp\$", $host)) { $pxck = "off"; } else { $pxck = "on"; } if ($pxck == "on" && PROXY_CHECK) { if (proxy_connect('80') == 1) { error("ERROR! 公開PROXY規制中!!(80)", $dest); } elseif (proxy_connect('8080') == 1) { error("ERROR! 公開PROXY規制中!!(8080)", $dest); } } // No.とパスと時間とURLフォーマット srand((double) microtime() * 1000000); if ($pwd == "") { if ($pwdc == "") { $pwd = rand(); $pwd = substr($pwd, 0, 8); } else { $pwd = $pwdc; } } $c_pass = $pwd; $pass = $pwd ? substr(md5($pwd), 2, 8) : "*"; $youbi = array('日', '月', '火', '水', '木', '金', '土'); $yd = $youbi[gmdate("w", $time + 9 * 60 * 60)]; $now = gmdate("y/m/d", $time + 9 * 60 * 60) . "(" . (string) $yd . ")" . gmdate("H:i", $time + 9 * 60 * 60); if (DISP_ID) { if ($email && DISP_ID == 1) { $now .= " ID:???"; } else { $now .= " ID:" . substr(crypt(md5($_SERVER["REMOTE_ADDR"] . IDSEED . gmdate("Ymd", $time + 9 * 60 * 60)), 'id'), -8); } } //テキスト整形 $email = CleanStr($email); $email = preg_replace("[\r\n]", "", $email); $sub = CleanStr($sub); $sub = preg_replace("[\r\n]", "", $sub); $url = CleanStr($url); $url = preg_replace("[\r\n]", "", $url); $resto = CleanStr($resto); $resto = preg_replace("[\r\n]", "", $resto); $com = CleanStr($com); // 改行文字の統一。 $com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com); // 連続する空行を一行 $com = preg_replace("\n(( | )*\n){3,}", "\n", $com); if (!BR_CHECK || substr_count($com, "\n") < BR_CHECK) { $com = nl2br($com); //改行文字の前に<br>を代入する } $com = str_replace("\n", "", $com); //\nを文字列から消す。 $name = preg_replace("◆", "◇", $name); $name = preg_replace("[\r\n]", "", $name); $names = $name; $name = CleanStr($name); if (preg_match("(#|#)(.*)", $names, $regs)) { $cap = $regs[2]; $cap = strtr($cap, "&", "&"); $cap = strtr($cap, ",", ","); $name = preg_replace("(#|#)(.*)", "", $name); $salt = substr($cap . "H.", 1, 2); $salt = preg_replace("[^\\.-z]", ".", $salt); $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef"); $name .= "</b>◆" . substr(crypt($cap, $salt), -10) . "<b>"; } if (!$name) { $name = "名無し"; } if (!$com) { $com = "本文なし"; } if (!$sub) { $sub = "無題"; } //ログ読み込み $fp = fopen(LOGFILE, "r+"); flock($fp, 2); rewind($fp); $buf = fread($fp, 1000000); if ($buf == '') { error("error load log", $dest); } $line = explode("\n", $buf); $countline = count($line); for ($i = 0; $i < $countline; $i++) { if ($line[$i] != "") { list($artno, ) = explode(",", rtrim($line[$i])); //逆変換テーブル作成 $lineindex[$artno] = $i + 1; $line[$i] .= "\n"; } } // 二重投稿チェック $imax = count($line) > 20 ? 20 : count($line) - 1; for ($i = 0; $i < $imax; $i++) { list($lastno, , $lname, , , $lcom, , $lhost, $lpwd, , , , $ltime, ) = explode(",", $line[$i]); if (strlen($ltime) > 10) { $ltime = substr($ltime, 0, -3); } if ($host == $lhost || substr(md5($pwd), 2, 8) == $lpwd || substr(md5($pwdc), 2, 8) == $lpwd) { $pchk = 1; } else { $pchk = 0; } if (RENZOKU && $pchk && $time - $ltime < RENZOKU) { error("連続投稿はもうしばらく時間を置いてからお願い致します", $dest); } if (RENZOKU && $pchk && $time - $ltime < RENZOKU2 && $upfile_name) { error("画像連続投稿はもうしばらく時間を置いてからお願い致します", $dest); } if (RENZOKU && $pchk && $com == $lcom && !$upfile_name) { error("連続投稿はもうしばらく時間を置いてからお願い致します", $dest); } } // ログ行数オーバー if (count($line) >= LOG_MAX) { for ($d = count($line) - 1; $d >= LOG_MAX - 1; $d--) { list($dno, , , , , , , , , $dext, , , $dtime, ) = explode(",", $line[$d]); if (is_file($path . $dtime . $dext)) { unlink($path . $dtime . $dext); } if (is_file(THUMB_DIR . $dtime . 's.jpg')) { unlink(THUMB_DIR . $dtime . 's.jpg'); } $line[$d] = ""; treedel($dno); } } // アップロード処理 if ($dest && file_exists($dest)) { $imax = count($line) > 200 ? 200 : count($line) - 1; for ($i = 0; $i < $imax; $i++) { //画像重複チェック list(, , , , , , , , , $extp, , , $timep, $chkp, ) = explode(",", $line[$i]); if ($chkp == $chk && file_exists($path . $timep . $extp)) { error("アップロードに失敗しました<br>同じ画像があります", $dest); } } } list($lastno, ) = explode(",", $line[0]); $no = $lastno + 1; isset($ext) ? 0 : ($ext = ""); isset($W) ? 0 : ($W = ""); isset($H) ? 0 : ($H = ""); isset($chk) ? 0 : ($chk = ""); $newline = "{$no},{$now},{$name},{$email},{$sub},{$com},{$url},{$host},{$pass},{$ext},{$W},{$H},{$tim},{$chk},\n"; $newline .= implode('', $line); ftruncate($fp, 0); set_file_buffer($fp, 0); rewind($fp); fputs($fp, $newline); //ツリー更新 $find = false; $newline = ''; $tp = fopen(TREEFILE, "r+"); set_file_buffer($tp, 0); rewind($tp); $buf = fread($tp, 1000000); if ($buf == '') { error("error tree update", $dest); } $line = explode("\n", $buf); $countline = count($line); for ($i = 0; $i < $countline; $i++) { if ($line[$i] != "") { $line[$i] .= "\n"; $j = explode(",", rtrim($line[$i])); if ($lineindex[$j[0]] == 0) { $line[$i] = ''; } } } if ($resto) { for ($i = 0; $i < $countline; $i++) { $rtno = explode(",", rtrim($line[$i])); if ($rtno[0] == $resto) { $find = TRUE; $line[$i] = rtrim($line[$i]) . ',' . $no . "\n"; $j = explode(",", rtrim($line[$i])); if (count($j) > MAX_RES) { $email = 'sage'; } if (!stristr($email, 'sage')) { $newline = $line[$i]; $line[$i] = ''; } break; } } } if (!$find) { if (!$resto) { $newline = "{$no}\n"; } else { error("スレッドがありません", $dest); } } $newline .= implode('', $line); ftruncate($tp, 0); set_file_buffer($tp, 0); rewind($tp); fputs($tp, $newline); fclose($tp); fclose($fp); //クッキー保存 setcookie("pwdc", $c_pass, time() + 7 * 24 * 3600); /* 1週間で期限切れ */ if (function_exists("mb_internal_encoding") && function_exists("mb_convert_encoding") && function_exists("mb_substr")) { if (preg_match("MSIE|Opera", $_SERVER["HTTP_USER_AGENT"])) { $i = 0; $c_name = ''; mb_internal_encoding("SJIS"); while ($j = mb_substr($names, $i, 1)) { $j = mb_convert_encoding($j, "UTF-16", "SJIS"); $c_name .= "%u" . bin2hex($j); $i++; } header("Set-Cookie: namec={$c_name}; expires=" . gmdate("D, d-M-Y H:i:s", time() + 7 * 24 * 3600) . " GMT", false); } else { $c_name = $names; setcookie("namec", $c_name, time() + 7 * 24 * 3600); /* 1週間で期限切れ */ } } if ($dest && file_exists($dest)) { rename($dest, $path . $tim . $ext); if (USE_THUMB) { thumb($path, $tim, $ext); } } updatelog(); echo "<html><head><META HTTP-EQUIV=\"refresh\" content=\"1;URL=" . PHP_SELF2 . "\"></head>"; echo "<body>{$mes} 画面を切り替えます</body></html>"; }
function _post() { $emo = isset($_POST['emotion']) ? intval($_POST['emotion']) : 0; $mesg = isset($_POST['message']) ? $_POST['message'] : ''; $mesg = CleanStr($mesg); if (!$mesg) { error("請填入內文"); } if (preg_match("/^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$/", $mesg)) { error('eMail禁止'); } if (strlen($mesg) > $this->MESSAGE_MAX) { error(_T('regist_commenttoolong')); } $mesg = str_replace("\n", " ", $mesg); // 消除換行 $mesg = str_replace(',', ',', $mesg); // 轉換"," $this->_loadCache(); $logs = @file($this->MESG_LOG); if ($logs === false) { $logs = array(); } if ($this->logcount + 1 > $this->LOG_MAX) { @array_splice($logs, $this->LOG_MAX - 2); } // chop by index // 檢查重複 if ($logs[0]) { list(, , , $lmsg, ) = explode(',', $logs[0]); if ($lmsg == $mesg) { return; } } $logs = ++$this->lastno . "," . ($now = time()) . "," . $this->EMOTIONS[$emo] . ",{$mesg},{$_SERVER['REMOTE_ADDR']},\n" . implode('', $logs); $this->_write($this->MESG_LOG, $logs); $this->_rebuildJSON($now, $this->EMOTIONS[$emo], $mesg); $this->_rebuildCache(); }
function regist() { //ログ書き込み global $name, $email, $sub, $com, $url, $tag, $past_key, $maxn, $maxs, $maxv, $maxline; global $password, $html_url, $gzlog, $jisa, $max, $w_regist, $autolink, $mudai, $PHP_SELF, $REQUEST_METHOD, $no_word; // 禁止ホスト hostblock(); //クッキー保存 $cookvalue = implode(",", array($name, $email, $password, $url)); setcookie("p_bbs", $cookvalue, time() + 14 * 24 * 3600); /* 2週間で期限切れ */ if ($REQUEST_METHOD != "POST") { error("不正な投稿をしないで下さい"); } if (GAIBU && !preg_match('/' . $PHP_SELF . '/i', getenv("HTTP_REFERER"))) { error("外部から書き込みできません"); } // フォーム内容をチェック if (!$name || preg_match("/^( | )*\$/", $name)) { if (ANONY_POST) { $name = "名無し"; } else { error("名前が書き込まれていません"); } } if (!$com || preg_match("/^( | |\t|\r|\n)*\$/", $com)) { error("本文が書き込まれていません"); } if (!$sub || preg_match("/^( | )*\$/", $sub)) { $sub = $mudai; } if (strlen($name) > $maxn) { error("名前が長すぎますっ!"); } if (strlen($sub) > $maxs) { error("タイトルが長すぎますっ!"); } if (strlen($com) > $maxv) { error("本文が長すぎますっ!"); } // 禁止ワード if (is_array($no_word)) { foreach ($no_word as $f**k) { if (preg_match("/{$f**k}/", $com)) { error("使用できない言葉が含まれています!"); } if (preg_match("/{$f**k}/", $sub)) { error("使用できない言葉が含まれています!"); } if (preg_match("/{$f**k}/", $name)) { error("使用できない言葉が含まれています!"); } } } $times = time(); $check = $gzlog ? ungzlog(LOGFILE) : file(LOGFILE); $tail = sizeof($check); list($tno, $tdate, $tname, $tmail, $tsub, $tcom, , , $tpw, $ttime) = explode("<>", $check[0]); if ($name == $tname && $com == $tcom) { error("二重投稿は禁止です"); } if ($w_regist && $times - $ttime < $w_regist) { error("連続投稿はもうしばらく時間を置いてからお願い致します"); } // 記事Noを採番 $no = $tno + 1; // ホスト名を取得 $host = getenv("REMOTE_HOST"); $addr = getenv("REMOTE_ADDR"); if ($host == "" || $host == $addr) { //gethostbyddrが使えるか $host = @gethostbyaddr($addr); } // 削除キーを暗号化 $PW = $password ? crypt($password, "aa") : ''; $now = gmdate("Y/m/d(D) H:i", time() + 9 * 60 * 60); $url = preg_replace("#^http://#", "", $url); CleanStr($com); CleanStr($sub); CleanStr($name); CleanStr($email); CleanStr($url); $name = str_replace("◆", "◇", $name); if (preg_match("/(#|#)(.*)/", $name, $regs)) { // 使用トリップ(Trip)機能 (ex:無名#abcd) $cap = $regs[2]; $cap = strtr($cap, array("&" => "&", "," => ",")); $name = preg_replace("/(#|#)(.*)/", "", $name); $salt = substr($cap . "H.", 1, 2); $salt = preg_replace("/[^\\.-z]/", ".", $salt); $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef"); $name .= "<code>◆" . substr(crypt($cap, $salt), -10) . "</code>"; } $com = str_replace(" ", " ", $com); $com = str_replace("\r\n", "\r", $com); //改行文字の統一。 $com = str_replace("\r", "\n", $com); /* \n数える(substr_countの代わり)*/ $temp = str_replace("\n", "\n" . "a", $com); $str_cnt = strlen($temp) - strlen($com); if ($str_cnt > $maxline) { error("行数が長すぎますっ!"); } $com = preg_replace("/\n(( | |\t)*\n){3,}/", "\n", $com); //連続する空行を一行 $com = nl2br($com); //改行文字の前に<br>を代入する。 $com = str_replace("\n", "", $com); //\nを文字列から消す。 $new_msg = "{$no}<>{$now}<>{$name}<>{$email}<>{$sub}<>{$com}<>{$url}<>{$host}<>{$PW}<>{$times}\n"; $old_log = $gzlog ? ungzlog(LOGFILE) : file(LOGFILE); list($ono, $odat, $oname, $oemail, $osub, $ocom, $ourl, $ohost, $opas) = @explode("<>", @$old_log[0]); if ($com == $ocom) { error("連続投稿はお止めください。"); } $line = sizeof($old_log); $new_log[0] = $new_msg; //先頭に新記事 if ($past_key && $line >= $max) { //はみ出した記事を過去ログへ for ($s = $max; $s <= $line; $s++) { //念の為複数行対応 past_log($old_log[$s - 1]); } } for ($i = 1; $i < $max; $i++) { //最大記事数処理 if ($i > count($old_log)) { break; } $new_log[$i] = $old_log[$i - 1]; } renewlog($new_log); //ログ更新 }
function regist($name, $email, $sub, $com, $url, $pwd) { global $REQUEST_METHOD, $path, $admin; if (!$admin) { error("Can't let you do that!"); } $line = file(LOGFILE); //Time post is created $tim = time(); $host = $_SERVER['REMOTE_ADDR']; //Reading from log file list($lastno, , $lname, , , $lcom, , $lhost, , , , , $ltime, ) = explode(",", $line[0]); //Post # calculation, sanitize strings $no = $lastno + 1; $c_pass = $pwd; $pass = $pwd ? substr(md5($pwd), 2, 8) : "*"; $now = gmdate("Y/m/d(D) H:i", $tim + 9 * 60 * 60); $name = CleanStr($name); $email = CleanStr($email); $sub = CleanStr($sub); $com = CleanStr($com); $com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com); $com = ereg_replace("\n(( | )*\n){3,}", "\n", $com); $com = nl2br($com); $com = str_replace("\n", "", $com); //Set cookies to remember name, email and del password values $cookvalue = implode(",", array($name, $email, $c_pass)); setcookie("gazoubbs", $cookvalue, time() + 14 * 24 * 3600); //Write data to log $newline = "{$no},{$now},{$name},{$email},{$sub},{$com},{$url},{$host},{$pass},{$ext},\n"; $fp = fopen(LOGFILE, "w"); flock($fp, 2); fputs($fp, $newline); fputs($fp, implode('', $line)); fclose($fp); echo "{$mes}"; echo "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=" . PHP_SELF . "?\">"; }
public function ModulePage() { $PIO = PMCLibrary::getPIOInstance(); if (!isset($_GET['no'])) { die('[Error] not enough parameter.'); } if (isset($_GET['action'])) { if (adminAuthenticate('check')) { $pushcount = ''; $puststart = 0; $post = $PIO->fetchPosts($_GET['no']); if (!count($post)) { die('[Error] Post does not exist.'); } // 被推之文章不存在 extract($post[0]); if ($status != '') { $f = $PIO->getPostStatus($status); $pushcount = $f->value('mppCnt'); // 被推次數 } if (($puststart = strpos($com, $this->PUSHPOST_SEPARATOR . '<br />')) === false) { die('[Error] No pushpost.'); } $ocom = substr($com, 0, $puststart); $pushpost = explode('<br />', substr($com, $puststart + strlen($this->PUSHPOST_SEPARATOR . '<br />'))); $com = $ocom; if ($_GET['action'] == 'del') { // list $p_count = 1; $com .= '<div class="pushpost">'; foreach ($pushpost as $p) { $com .= '<input type="checkbox" name="' . $p_count++ . '" value="delete" />' . $p . '<br />'; } $com .= '</div>'; $dat = ''; head($dat); $dat .= '<div class="bar_reply">' . $this->_T('deletepush') . '</div>'; $dat .= '<form action="' . $this->getModulePageURL(array('action' => 'delpush', 'no' => $_GET['no'])) . '" method="post">'; $dat .= PMCLibrary::getPTEInstance()->ParseBlock('SEARCHRESULT', array('{$NO}' => $no, '{$SUB}' => $sub, '{$NAME}' => $name, '{$NOW}' => $now, '{$COM}' => $com, '{$CATEGORY}' => $category, '{$NAME_TEXT}' => _T('post_name'), '{$CATEGORY_TEXT}' => _T('post_category'))); echo $dat, '<input type="submit" value="' . _T('del_btn') . '" /></form></body></html>'; return; } else { if ($_GET['action'] == 'delpush') { // delete $delno = array(); reset($_POST); while ($item = each($_POST)) { if ($item[1] == 'delete' && $item[0] != 'func') { array_push($delno, $item[0]); } } if (count($delno)) { foreach ($delno as $d) { if (isset($pushpost[$d - 1])) { unset($pushpost[$d - 1]); } } } $pushcount = count($pushpost); if ($pushcount) { $f->update('mppCnt', $pushcount); // 更新推文次數 $com = $ocom . $this->PUSHPOST_SEPARATOR . '<br />' . implode('<br />', $pushpost); } else { $f->remove('mppCnt'); // 刪除推文次數 $com = $ocom; } $PIO->updatePost($_GET['no'], array('com' => $com, 'status' => $f->toString())); // 更新推文 $PIO->dbCommit(); header('HTTP/1.1 302 Moved Temporarily'); header('Location: ' . fullURL() . PHP_SELF . '?page_num=0'); return; } else { die('[Error] unknown action.'); } } } else { die('[Error] unauthenticated action.'); } } // 非 AJAX 推文,產出表單供填寫 if (!isset($_POST['comm'])) { echo $this->printStaticForm(intval($_GET['no'])); } else { // 處理推文 // 傳送方法不正確 if ($_SERVER['REQUEST_METHOD'] != 'POST') { die(_T('regist_notpost')); } // 查IP $baninfo = ''; $ip = getREMOTE_ADDR(); $host = gethostbyaddr($ip); if (BanIPHostDNSBLCheck($ip, $host, $baninfo)) { die(_T('regist_ipfiltered', $baninfo)); } $name = CleanStr($_POST['name']); $comm = CleanStr($_POST['comm']); if (strlen($name) > 30) { die($this->_T('maxlength')); } // 名稱太長 if (strlen($comm) > 160) { die($this->_T('maxlength')); } // 太多字 if (strlen($comm) == 0) { die($this->_T('nocomment')); } // 沒打字 $name = str_replace(array(_T('trip_pre'), _T('admin'), _T('deletor')), array(_T('trip_pre_fake'), '"' . _T('admin') . '"', '"' . _T('deletor') . '"'), $name); // 生成ID, Trip 等識別資訊 $pushID = $this->getID(); $pushtime = gmdate('y/m/d H:i', time() + intval(TIME_ZONE) * 3600); if (preg_match('/(.*?)[##](.*)/u', $name, $regs)) { $cap = strtr($regs[2], array('&' => '&')); $salt = strtr(preg_replace('/[^\\.-z]/', '.', substr($cap . 'H.', 1, 2)), ':;<=>?@[\\]^_`', 'ABCDEFGabcdef'); $name = $regs[1] . _T('trip_pre') . substr(crypt($cap, $salt), -10); } if (!$name || preg_match("/^[ | |]*\$/", $name)) { if (ALLOW_NONAME) { $name = DEFAULT_NONAME; } else { die(_T('regist_withoutname')); } // 不接受匿名 } if (ALLOW_NONAME == 2) { // 強制砍名 $name = preg_match('/(\\' . _T('trip_pre') . '.{10})/', $name, $matches) ? $matches[1] . ':' : DEFAULT_NONAME . ':'; } else { $name .= ':'; } $pushpost = "{$name} {$comm} ({$pushID} {$pushtime})"; // 推文主體 $post = $PIO->fetchPosts($_GET['no']); if (!count($post)) { die('[Error] Post does not exist.'); } // 被推之文章不存在 $parentNo = $post[0]['resto'] ? $post[0]['resto'] : $post[0]['no']; $threads = array_flip($PIO->fetchThreadList()); $threadPage = floor($threads[$parentNo] / PAGE_DEF); $p = $parentNo == $post[0]['no'] ? $post : $PIO->fetchPosts($parentNo); // 取出首篇 $flgh = $PIO->getPostStatus($p[0]['status']); if ($flgh->exists('TS')) { die('[Error] ' . _T('regist_threadlocked')); } // 首篇禁止回應/同時表示禁止推文 $post[0]['com'] .= (strpos($post[0]['com'], $this->PUSHPOST_SEPARATOR . '<br />') === false ? '<br />' . $this->PUSHPOST_SEPARATOR : '') . '<br /> ' . $pushpost; $flgh2 = $PIO->getPostStatus($post[0]['status']); $flgh2->plus('mppCnt'); // 推文次數+1 $PIO->updatePost($_GET['no'], array('com' => $post[0]['com'], 'status' => $flgh2->toString())); // 更新推文 $PIO->dbCommit(); // mod_audit logcat $this->callCHP('mod_audit_logcat', array(sprintf('[%s] No.%d %s (%s)', __CLASS__, $_GET['no'], $comm, $pushID))); if (STATIC_HTML_UNTIL == -1 || $threadPage <= STATIC_HTML_UNTIL) { // 僅更新討論串出現那頁 updatelog(0, $threadPage, true); } deleteCache(array($parentNo)); // 刪除討論串舊快取 if (isset($_POST['ajaxmode'])) { echo '+OK ', $pushpost; } else { header('HTTP/1.1 302 Moved Temporarily'); header('Location: ' . fullURL() . PHP_SELF2 . '?' . time()); } } }
function addPost() { $pwdc = isset($_COOKIE["pwdc"]) ? $_COOKIE["pwdc"] : ""; $url = ''; if ($_SERVER["REQUEST_METHOD"] != "POST") { error("請使用此版提供的表單來上傳", $dest); } if (isset($_POST[$tmpField = getFieldName(true)])) { $name = isset($_POST[$tmpField]) ? $_POST[$tmpField] : ''; $email = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; $sub = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; $com = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; } else { $name = isset($_POST[$tmpField = getFieldName(gmdate("Ymd", date()) - 1)]) ? $_POST[$tmpField] : ''; $email = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; $sub = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; $com = isset($_POST[$tmpField = getFieldName()]) ? $_POST[$tmpField] : ''; } $pwd = isset($_POST['pwd']) ? $_POST['pwd'] : ''; $res = isset($_POST['res']) ? $_POST['res'] : 0; // 欄位陷阱 $FTname = isset($_POST['name']) ? $_POST['name'] : ''; $FTemail = isset($_POST['email']) ? $_POST['email'] : ''; $FTsub = isset($_POST['sub']) ? $_POST['sub'] : ''; $FTcom = isset($_POST['com']) ? $_POST['com'] : ''; $FTreply = isset($_POST['reply']) ? $_POST['reply'] : ''; if ($FTname != 'spammer' || $FTemail != '*****@*****.**' || $FTsub != 'DO NOT FIX THIS' || $FTcom != 'EID OG SMAPS' || $FTreply != '') { error("Trapped."); } // 時間 $time = time(); $tim = $time . substr(microtime(), 2, 3); // 讀取記錄檔 $fp = fopen(DATAFILE, "r+"); flock($fp, 2); rewind($fp); $buf = @fread($fp, filesize(DATAFILE)); if ($buf == '') { error("讀取記錄檔時發生錯誤"); } $line = explode("\n", $buf); $countline = count($line); for ($i = 0; $i < $countline; $i++) { if ($line[$i] != "") { list($artno, ) = explode(",", rtrim($line[$i])); // 作成逆轉換標籤 $lineindex[$artno] = $i + 1; $line[$i] .= "\n"; } } // 檢查表單內容 if (!$name || preg_match("/^[ | |]*\$/", $name)) { $name = ""; } if (!$com || preg_match("/^[ | |\t]*\$/", $com)) { $com = ""; } if (!$sub || preg_match("/^[ | |]*\$/", $sub)) { $sub = ""; } $name = str_replace("管理", '"管理"', $name); $name = str_replace("刪除", '"刪除"', $name); if (strlen($com) > COM_MAX && $pwd != ADMIN_PASS) { error("內文過長"); } if (strlen($name) > 100) { error("名稱過長"); } if (strlen($email) > 100) { error("E-mail過長"); } if (strlen($sub) > 100) { error("標題過長"); } if (strlen($res) > 10) { error("欲回應的文章編號可能有誤"); } // 取得主機位置名稱 $host = gethostbyaddr($_SERVER["REMOTE_ADDR"]); // 時間和密碼的樣式 srand((double) microtime() * 1000000); if ($pwd == "") { if ($pwdc == "") { $pwd = rand(); $pwd = substr($pwd, 0, 8); } else { $pwd = $pwdc; } } $c_pass = $pwd; $pass = $pwd ? substr(md5($pwd), 2, 8) : "*"; $youbi = array('日', '一', '二', '三', '四', '五', '六'); $yd = $youbi[gmdate("w", $time + TIME_ZONE * 60 * 60)]; $now = gmdate("y/m/d", $time + TIME_ZONE * 60 * 60) . "(" . (string) $yd . ")" . gmdate("H:i", $time + TIME_ZONE * 60 * 60); if (DISP_ID) { // 顯示ID if ($email && DISP_ID == 1) { $now .= " ID:???"; } else { $now .= " ID:" . substr(crypt(md5($_SERVER["REMOTE_ADDR"] . TITLE . gmdate("Ymd", $time + TIME_ZONE * 60 * 60)), 'id'), -8); } } // 文字修整 $email = CleanStr($email); $email = str_replace("\r\n", "", $email); $sub = CleanStr($sub); $sub = str_replace("\r\n", "", $sub); $url = CleanStr($url); $url = str_replace("\r\n", "", $url); $res = CleanStr($res); $res = str_replace("\r\n", "", $res); $com = CleanStr($com); // 換行字元統一 $com = str_replace("\r\n", "\n", $com); $com = str_replace("\r", "\n", $com); // 去除連續空白 $com = preg_replace("/\n(( | )*\n){3,}/", "\n", $com); $com = str_replace("\n", '<br/>', $com); // 換行字元用<br />代替 $com = str_replace("\n", " ", $com); // 若還有\n換行字元則取消換行 $name = str_replace("◆", "◇", $name); // 防止トリップ偽造 $name = str_replace("★", "☆", $name); // 防止キャップ偽造 $name = str_replace("\r\n", "", $name); $name = CleanStr($name); $tripped_name = ""; // 給キャップ(Cap)機能讀取之Trip樣式 if (preg_match("/(#|#)(.*)/", $name, $regs)) { // 使用トリップ(Trip)機能 (ex:無名#abcd) $cap = $regs[2]; $cap = strtr($cap, array("&" => "&", "," => ",")); $name = preg_replace("/(#|#)(.*)/", "", $name); $salt = substr($cap . "H.", 1, 2); $salt = preg_replace("/[^\\.-z]/", ".", $salt); $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef"); $trip = substr(crypt($cap, $salt), -10); $tripped_name = trim($name) . "◆{$trip}"; $name .= "<span class='nor'>◆{$trip}</span>"; } if (strpos($name, "fusianasan") !== false) { $name = str_replace("fusianasan", "<span class='nor'>" . $host . "</span>", $name); } if (strpos($name, "mokorikomo") !== false) { $name = str_replace("mokorikomo", "<span class='nor'>" . $_SERVER['REMOTE_ADDR'] . "</span>", $name); } if (!$name) { $name = "無名氏"; } // 管理員投稿名稱特別色 if ($pwd == ADMIN_PASS) { $name = "<span class='Cname_admin'>" . $name . "</span>"; } // if(!$com) $com = "無內文"; if (!$com) { error("請填入內文"); } if (!$sub) { $sub = "無標題"; } list($lastno, ) = explode(",", $line[0]); $no = $lastno + 1; isset($ext) ? 0 : ($ext = ""); isset($W) ? 0 : ($W = ""); isset($H) ? 0 : ($H = ""); isset($chk) ? 0 : ($chk = ""); $newline = "{$no},{$now},{$name},{$email},{$sub},{$com},{$url},{$host},{$pass},{$ext},{$W},{$H},{$tim},{$chk},\n"; $newline .= implode('', $line); ftruncate($fp, 0); set_file_buffer($fp, 0); rewind($fp); fputs($fp, $newline); // 樹狀結構記錄檔更新 $newline = ''; $tp = fopen(TREEFILE, "r+"); set_file_buffer($tp, 0); rewind($tp); $buf = @fread($tp, filesize(TREEFILE)); if ($buf == '') { error("更新樹狀結構記錄檔時發生錯誤"); } $treeline = explode("\n", $buf); $counttree = count($treeline); for ($i = 0; $i < $counttree; $i++) { if ($treeline[$i] != "") { $treeline[$i] .= "\n"; $j = explode(",", rtrim($treeline[$i])); if ($lineindex[$j[0]] == 0) { $line[$i] = ''; } } } if ($res) { for ($i = 0; $i < $counttree; $i++) { $rtno = explode(",", rtrim($treeline[$i])); if ($rtno[0] == $res) { $treeline[$i] = rtrim($treeline[$i]) . ',' . $no . "\n"; $j = explode(",", rtrim($treeline[$i])); if (!preg_match('/^sage/i', ltrim($email))) { $newline = $treeline[$i]; $treeline[$i] = ''; } break; } } } if (!$res) { $newline = "{$no}\n"; } $newline .= implode('', $treeline); ftruncate($tp, 0); set_file_buffer($tp, 0); rewind($tp); fputs($tp, $newline); fclose($tp); fclose($fp); error('<script type="text/javascript"> function redir(){ location.href = "' . $_SERVER['PHP_SELF'] . '"; } setTimeout("redir()", 1000); </script> 請等候跳轉…… '); }
<form method="post" action="' . $_SERVER['PHP_SELF'] . '"> <input type="hidden" name="key" value="' . $key . '"><input type="hidden" name="nick" value="' . $FROM1 . '"><input type="hidden" name="mail" value="' . $mail . '"><br> <input type="hidden" name="subject" value="' . $subject . '"> <input type="hidden" name="content" value="' . $MESSAGE . '"><input type="hidden" name="url" value=""> <input type="hidden" name="delk" value="' . $c_pass . '">'; echo recaptcha_get_html($publickey, $error); echo '<input type="submit" value="確認"> </form> </body></html>'; return false; } $subject = CleanStr($_REQUEST['subject']); $FROM1 = $_REQUEST['nick']; $FROM = CleanStr($_REQUEST['nick']); $FROM = preg_replace("/[\r\n]/", "", $FROM); $MESSAGE = CleanStr($_REQUEST['content']); $mail = Cleanstr($_REQUEST['mail']); $c_pass = $_REQUEST['delk']; $delk = substr(md5($_REQUEST['delk']), 2, 8); $key = $_REQUEST['key']; $HOST = gethostbyaddr($IP = getREMOTE_ADDR()); $idtag = false; if (preg_match("/^( | |\t)*\$/", $MESSAGE)) { error("本文がありません!", $FROM, $mail, $HOST, $MESSAGE); } if ($key == "" && preg_match("/^( | |\t)*\$/", $subject)) { error("サブジェクトが存在しません!", $FROM, $mail, $HOST, $MESSAGE); } if (!isset($_REQUEST['url']) || isset($_REQUEST['url']) && $_REQUEST['url'] != "") { error("投稿が禁止されています", $FROM, $mail, $HOST, $MESSAGE); }
function _postPM($from, $to, $topic, $mesg) { if (!preg_match('/^[0-9a-zA-Z\\.\\/]{10}$/', $to)) { error("Trip有誤"); } $from = CleanStr($from); $to = CleanStr($to); $topic = CleanStr($topic); $mesg = CleanStr($mesg); if (!$from) { if (ALLOW_NONAME) { $from = DEFAULT_NONAME; } } if (!$topic) { $topic = DEFAULT_NOTITLE; } if (!$mesg) { error("請填入內文"); } if (preg_match('/(.*?)[##](.*)/u', $from, $regs)) { // トリップ(Trip)機能 $from = $nameOri = $regs[1]; $cap = strtr($regs[2], array('&' => '&')); $from = $from . '<span class="nor">' . _T('trip_pre') . $this->_tripping($cap) . "</span>"; } $from = str_replace(_T('admin'), '"' . _T('admin') . '"', $from); $from = str_replace(_T('deletor'), '"' . _T('deletor') . '"', $from); $from = str_replace('&' . _T('trip_pre'), '&' . _T('trip_pre'), $from); // 避免 &#xxxx; 後面被視為 Trip 留下 & 造成解析錯誤 $mesg = str_replace(',', ',', $mesg); // 轉換"," $mesg = str_replace("\n", '<br/>', $mesg); //nl2br不行 $this->_loadCache(); $logs = ++$this->lastno . ",{$to}," . time() . ",{$from},{$topic},{$mesg},{$_SERVER['REMOTE_ADDR']},\n" . @file_get_contents($this->MESG_LOG); $this->_write($this->MESG_LOG, $logs); $this->_rebuildCache(); }