/** * ImageCache2 の一時的な有効・無効を切り替える * * @param bool $switch * @param bool $mobile * @return bool */ public static function set($switch, $mobile = false) { global $_conf; $switch_file = $_conf['expack.ic2.switch_path']; if (!file_exists($switch_file)) { FileCtl::make_datafile($switch_file); $flags = self::ENABLED_ALL; } else { $flags = self::ENABLED_ALL & filesize($switch_file); } if ($switch) { if ($mobile) { $flags |= self::ENABLED_MOBILE; } else { $flags |= self::ENABLED_PC; } } else { if ($mobile) { $flags &= ~self::ENABLED_MOBILE; } else { $flags &= ~self::ENABLED_PC; } } if ($flags > 0) { $data = str_repeat('*', $flags); } else { $data = ''; } return file_put_contents($switch_file, $data, LOCK_EX) === $flags; }
/** * お気にスレをセットする関数 * * $setfav は、'0'(解除), '1'(追加), 'top', 'up', 'down', 'bottom' * * @access public * @return boolean */ function setFav($host, $bbs, $key, $setfav) { global $_conf; if (P2Validate::host($host) || P2Validate::bbs($bbs) || P2Validate::key($key)) { return false; } // スレッド.idx 記録 $data = _setFavToKeyIdx($host, $bbs, $key, $setfav); $newlines = array(); $before_line_num = 0; if (false === FileCtl::make_datafile($_conf['favlist_file'], $_conf['favlist_perm'])) { return false; } if (false === ($favlines = file($_conf['favlist_file']))) { return false; } // 最初に重複要素を削除しておく if (!empty($favlines)) { $i = -1; foreach ($favlines as $line) { $i++; $line = rtrim($line); $lar = explode('<>', $line); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } elseif (P2Validate::host($lar[10]) || P2Validate::bbs($lar[11]) || P2Validate::key($lar[1])) { continue; } else { $newlines[] = $line; } } } if (!empty($GLOBALS['brazil'])) { //$newlines = _removeLargeFavlistData($newlines); } // 記録データ設定 if ($setfav) { $newdata = implode('<>', array(geti($data[0]), $key, geti($data[2]), geti($data[3]), geti($data[4]), geti($data[5]), 1, geti($data[7]), geti($data[8]), geti($data[9]), $host, $bbs)); require_once P2_LIB_DIR . '/getSetPosLines.func.php'; $rec_lines = getSetPosLines($newlines, $newdata, $before_line_num, $setfav); } else { $rec_lines = $newlines; } if (false === file_put_contents($_conf['favlist_file'], $rec_lines ? implode("\n", $rec_lines) . "\n" : '', LOCK_EX)) { trigger_error(sprintf('file_put_contents(%s)', $_conf['favlist_file']), E_USER_WARNING); return false; } // お気にスレ共有 _setFavRank($host, $bbs, $key, $setfav, geti($data[0])); return true; }
/** * ファイル内容を読み込んで編集する関数 */ function editFile($path, $encode, $title) { global $_conf, $modori_url, $rows, $cols, $csrfid; if ($path == '') { p2die('path が指定されていません'); } $filename = basename($path); $ptitle = 'Edit: ' . p2h($title) . ' (' . $filename . ')'; //ファイル内容読み込み FileCtl::make_datafile($path) or p2die("cannot make file. ({$path})"); $cont = file_get_contents($path); if ($encode == "EUC-JP") { $cont = mb_convert_encoding($cont, 'CP932', 'CP51932'); } $cont_area = p2h($cont); if ($modori_url) { $modori_url_ht = "<p><a href=\"{$modori_url}\">Back</a></p>\n"; } else { $modori_url_ht = ''; } $rows_at = $rows > 0 ? sprintf(' rows="%d"', $rows) : ''; $cols_at = $cols > 0 ? sprintf(' cols="%d"', $cols) : ''; // プリント echo $_conf['doctype']; echo <<<EOHEADER <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> {$_conf['extra_headers_ht']} <title>{$ptitle}</title> </head> <body onload="top.document.title=self.document.title;"> EOHEADER; $info_msg_ht = P2Util::getInfoHtml(); echo $modori_url_ht; echo $ptitle; echo <<<EOFORM <form action="{$_SERVER['SCRIPT_NAME']}" method="post" accept-charset="{$_conf['accept_charset']}"> <input type="hidden" name="file" value="{$filename}"> <input type="hidden" name="modori_url" value="{$modori_url}"> <input type="hidden" name="encode" value="{$encode}"> <input type="hidden" name="rows" value="{$rows}"> <input type="hidden" name="cols" value="{$cols}"> <input type="hidden" name="csrfid" value="{$csrfid}"> <input type="submit" name="submit" value="Save"> {$info_msg_ht}<br> <textarea style="font-size:9pt;" id="filecont" name="filecont" wrap="off"{$rows_at}{$cols_at}>{$cont_area}</textarea> {$_conf['detect_hint_input_ht']}{$_conf['k_input_ht']} </form> EOFORM; echo '</body></html>'; return true; }
/** * スレを殿堂入りにセットする関数 * * $set は、0(解除), 1(追加), top, up, down, bottom * * @access public * @return boolean */ function setPalace($host, $bbs, $key, $set) { global $_conf; $idxfile = P2Util::getKeyIdxFilePath($host, $bbs, $key); // 既に key.idx データがあるなら読み込む if (file_exists($idxfile) and $lines = file($idxfile)) { $l = rtrim($lines[0]); $data = explode('<>', $l); } if (false === FileCtl::make_datafile($_conf['palace_file'], $_conf['palace_perm'])) { return false; } if (false === ($pallines = file($_conf['palace_file']))) { return false; } $newlines = array(); $before_line_num = 0; // {{{ 最初に重複要素を削除しておく if (!empty($pallines)) { $i = -1; foreach ($pallines as $l) { $i++; $l = rtrim($l); $lar = explode('<>', $l); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } else { $newlines[] = $l; } } } // }}} if (!empty($GLOBALS['brazil'])) { //$newlines = _removeLargePallistData($newlines); } // 新規データ設定 if ($set) { $newdata = implode('<>', array(geti($data[0]), $key, geti($data[2]), geti($data[3]), geti($data[4]), geti($data[5]), geti($data[6]), geti($data[7]), geti($data[8]), geti($data[9]), $host, $bbs)); require_once P2_LIB_DIR . '/getSetPosLines.func.php'; $rec_lines = getSetPosLines($newlines, $newdata, $before_line_num, $set); } else { $rec_lines = $newlines; } if (false === FileCtl::filePutRename($_conf['palace_file'], $rec_lines ? implode("\n", $rec_lines) . "\n" : '')) { trigger_error(sprintf('p2 error: %s(), FileCtl::filePutRename() failed.', __FUNCTION__), E_USER_WARNING); return false; } return true; }
/** * コンストラクタ * * @param string $filename * @param bool $allow_linebreaks */ public function __construct($filename, $allow_linebreaks = false) { if (!file_exists($filename)) { FileCtl::make_datafile($filename); $this->_data = array(); } else { $content = FileCtl::file_read_contents($filename); if (!$content || !is_array($this->_data = @unserialize($content))) { $this->_data = array(); } } $this->_filename = $filename; $this->_allowLinebreaks = $allow_linebreaks; }
public function load_cache() { global $_conf; $lines = array(); $path = $_conf['pref_dir'] . '/' . $this->cacheFilename; FileCtl::make_datafile($path); if ($lines = @file($path)) { foreach ($lines as $l) { list($key, $data) = explode("\t", trim($l)); if (strlen($key) == 0 || strlen($data) == 0) { continue; } $this->cacheData[$key] = unserialize($data); } } $this->cacheIsLoaded = true; return $this->cacheData; }
/** * 新着まとめ読みのキャッシュを残す * * @access public * register_shutdown_function() から呼ばれる。(相対パスのファイルは扱えない?) */ function saveMatomeCache() { global $_conf; if (!empty($GLOBALS['_is_matome_shinchaku_naipo'])) { return true; } // ローテーション $max = $_conf['matome_cache_max']; $i = $max; while ($i >= 0) { $di = $i == 0 ? '' : '.' . $i; $tfile = $_conf['matome_cache_path'] . $di . $_conf['matome_cache_ext']; $next = $i + 1; $nfile = $_conf['matome_cache_path'] . '.' . $next . $_conf['matome_cache_ext']; if (file_exists($tfile)) { if ($i == $max) { unlink($tfile); } else { if (strstr(PHP_OS, 'WIN') and file_exists($nfile)) { unlink($nfile); } rename($tfile, $nfile); } } $i--; } // 新規記録 $file = $_conf['matome_cache_path'] . $_conf['matome_cache_ext']; //echo "<!-- {$file} -->"; FileCtl::make_datafile($file, $_conf['p2_perm']); if (false === file_put_contents($file, $GLOBALS['_read_new_html'], LOCK_EX)) { trigger_error(sprintf('file_put_contents(%s)', $file), E_USER_WARNING); die('Error: cannot write file.'); return false; } return true; }
/** * フィルタリング設定をファイルに保存する * * @param void * @return void */ public function save() { global $_conf; $cachefile = $_conf['pref_dir'] . '/p2_res_filter.txt'; FileCtl::make_datafile($cachefile, $_conf['p2_perm']); $res_filter_cont = serialize(array('field' => $this->field, 'method' => $this->method, 'match' => $this->match, 'include' => $this->include)); FileCtl::file_write_contents($cachefile, $res_filter_cont); }
/** * brdファイルを生成する * * @return string brdファイルのパス */ public function makeBrdFile($cachefile) { global $_conf, $word; $p2brdfile = $cachefile . ".p2.brd"; FileCtl::make_datafile($p2brdfile); $data = FileCtl::file_read_lines($cachefile); $cont = ''; $this->setBrdMatch($cachefile); // パターンマッチ形式を登録 $this->setBrdList($data); // カテゴリーと板をセット if ($this->categories) { foreach ($this->categories as $cate) { if ($cate->num > 0) { $cont .= $cate->name . "\t0\n"; foreach ($cate->menuitas as $mita) { $cont .= "\t{$mita->host}\t{$mita->bbs}\t{$mita->itaj}\n"; } } } } if ($cont) { if (FileCtl::file_write_contents($p2brdfile, $cont) === false) { p2die("{$p2brdfile} を更新できませんでした"); } return $p2brdfile; } else { if (!$word) { P2Util::pushInfoHtml("<p>p2 error: {$cachefile} から板メニューを生成することはできませんでした。</p>"); } return false; } }
/** * スキン設定を更新し、ページをリロードする * * @return false 成功すれば、そのままページリダイレクトされる */ function _updateSkinSetting($newskin) { global $_conf; if ($newskin !== '') { if (!preg_match('/^\\w+$/', $newskin)) { P2Util::pushInfoHtml(sprintf("<p>p2 error: 不正なスキン (%s) が指定されました。</p>", hs($newskin))); return false; } $skinFilePath = P2Util::getSkinFilePathBySkinName($newskin); if (!file_exists($skinFilePath)) { P2Util::pushInfoHtml(sprintf("<p>p2 error: 不正なスキン (%s) が指定されました。</p>", hs($newskin))); return false; } } FileCtl::make_datafile($_conf['skin_setting_path'], $_conf['skin_setting_perm']); if (false === file_put_contents($_conf['skin_setting_path'], $newskin, LOCK_EX)) { P2Util::pushInfoHtml("<p>p2 error: スキン設定を書き込めませんでした。</p>"); return false; } $sid_q = defined('SID') && strlen(SID) ? '&' . SID : ''; header("Location: {$_SERVER['SCRIPT_NAME']}?reload_skin=1" . $sid_q); exit; }
/** * 2chの過去ログ倉庫からdat.gzをダウンロード&解凍する * * @access private * @return true|string|false 取得できたか、更新がなかった場合はtrue(または"304 Not Modified")を返す */ function downloadDat2chKako($uri, $ext) { global $_conf; $url = $uri . $ext; $purl = parse_url($url); // クエリー $purl['query'] = isset($purl['query']) ? '?' . $purl['query'] : ''; // プロキシ if ($_conf['proxy_use']) { $send_host = $_conf['proxy_host']; $send_port = $_conf['proxy_port']; $send_path = $url; } else { $send_host = $purl['host']; $send_port = isset($purl['port']) ? $purl['port'] : null; $send_path = $purl['path'] . $purl['query']; } // デフォルトを80 if (!$send_port) { $send_port = 80; } $request = 'GET ' . $send_path . " HTTP/1.0\r\n"; $request .= "Host: " . $purl['host'] . "\r\n"; $request .= "User-Agent: " . P2Util::getP2UA($withMonazilla = true) . "\r\n"; $request .= "Connection: Close\r\n"; //$request .= "Accept-Encoding: gzip\r\n"; /* if ($modified) { $request .= "If-Modified-Since: $modified\r\n"; } */ $request .= "\r\n"; // WEBサーバへ接続 $fp = fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']); if (!$fp) { P2Util::pushInfoHtml(sprintf('<p>サーバ接続エラー: %s (%s)<br>p2 info - %s に接続できませんでした。</div>', hs($errstr), hs($errno), P2View::tagA(P2Util::throughIme($url), hs($url), array('target' => $_conf['ext_win_target'])))); $this->diedat = true; return false; } // HTTPリクエスト送信 fputs($fp, $request); // HTTPヘッダレスポンスを取得する $h = $this->freadHttpHeader($fp); if ($h === false) { fclose($fp); $this->_pushInfoHtmlFreadHttpHeaderError($url); $this->diedat = true; return false; } // {{{ HTTPコードをチェック $code = $h['code']; // Partial Content if ($code == "200") { // OK。何もしない // Not Modified } elseif ($code == "304") { fclose($fp); //$this->isonline = true; return "304 Not Modified"; // 予期しないHTTPコード。なかったと判断 } else { fclose($fp); $this->downloadDat2chKakoNotFound($uri, $ext); return false; } // }}} if (isset($h['headers']['Last-Modified'])) { $lastmodified = $h['headers']['Last-Modified']; } if (isset($h['headers']['Content-Length'])) { if (preg_match("/^([0-9]+)/", $h['headers']['Content-Length'], $matches)) { $onbytes = $h['headers']['Content-Length']; } } $isGzip = false; if (isset($h['headers']['Content-Encoding'])) { if (preg_match("/^(x-)?gzip/", $h['headers']['Content-Encoding'], $matches)) { $isGzip = true; } } // bodyを読む $body = ''; while (!feof($fp)) { $body .= fread($fp, 8192); } fclose($fp); $done_gunzip = false; if ($isGzip) { $gztempfile = $this->keydat . '.gz'; FileCtl::mkdirFor($gztempfile); if (file_put_contents($gztempfile, $body, LOCK_EX) === false) { die("Error: cannot write file. downloadDat2chKako()"); return false; } if (extension_loaded('zlib')) { $body = FileCtl::getGzFileContents($gztempfile); } else { // 既に存在するなら一時バックアップ退避 $keydat_bak = $this->keydat . '.bak'; if (file_exists($this->keydat)) { if (file_exists($keydat_bak)) { unlink($keydat_bak); } rename($this->keydat, $keydat_bak); } $rcode = 1; // 解凍 system("gzip -d {$gztempfile}", $rcode); if ($rcode != 0) { if (file_exists($keydat_bak)) { if (file_exists($this->keydat)) { unlink($this->keydat); } // 失敗ならバックアップ戻す rename($keydat_bak, $this->keydat); } $this->pushDownloadDatErrorMsgHtml("<p>p2 info - 2ちゃんねる過去ログ倉庫からのスレッド取り込みは、PHPの<a href=\"http://www.php.net/manual/ja/ref.zlib.php\">zlib拡張モジュール</a>がないか、systemでgzipコマンドが使用可能\でなければできません。</p>"); // gztempファイルを捨てる file_exists($gztempfile) and unlink($gztempfile); $this->diedat = true; return false; } else { if (file_exists($keydat_bak)) { unlink($keydat_bak); } $done_gunzip = true; } } // tempファイルを捨てる file_exists($gztempfile) and unlink($gztempfile); } if (!$done_gunzip) { FileCtl::make_datafile($this->keydat, $_conf['dat_perm']); if (false === file_put_contents($this->keydat, $body, LOCK_EX)) { die("Error: cannot write file. downloadDat2chKako()"); return false; } } //$this->isonline = true; return true; }
/** * 2ch●ログインのIDとPASSと自動ログイン設定を保存する */ public static function saveIdPw2ch($login2chID, $login2chPW, $autoLogin2ch = false) { global $_conf; $md5_crypt_key = self::getAngoKey(); $escaped_login2chID = addslashes($login2chID); $crypted_login2chPW = MD5Crypt::encrypt($login2chPW, $md5_crypt_key, 32); $boolstr_autoLogin2ch = $autoLogin2ch ? 'true' : 'false'; $idpw2ch_cont = <<<EOP <?php \$rec_login2chID = '{$escaped_login2chID}'; \$rec_login2chPW = '{$crypted_login2chPW}'; \$rec_autoLogin2ch = {$boolstr_autoLogin2ch}; EOP; FileCtl::make_datafile($_conf['idpw2ch_php'], $_conf['pass_perm']); // ファイルがなければ生成 $fp = @fopen($_conf['idpw2ch_php'], 'wb'); if (!$fp) { p2die("{$_conf['idpw2ch_php']} を更新できませんでした"); } flock($fp, LOCK_EX); fputs($fp, $idpw2ch_cont); flock($fp, LOCK_UN); fclose($fp); return true; }
/** * お気に入りセットリストを更新する * * @return boolean 更新に成功したらTRUE, 失敗したらFALSE */ function updateFavSetList() { global $_conf; if (file_exists($_conf['expack.misc.favset_file'])) { $setlist_titles = FavSetManager::getFavSetTitles(); } else { FileCtl::make_datafile($_conf['expack.misc.favset_file']); } if (empty($setlist_titles)) { $setlist_titles = array(); } $setlist_names = array('m_favlist_set', 'm_favita_set', 'm_rss_set'); foreach ($setlist_names as $setlist_name) { if (isset($_POST["{$setlist_name}_titles"]) && is_array($_POST["{$setlist_name}_titles"])) { $setlist_titles[$setlist_name] = array(); for ($i = 0; $i <= $_conf['expack.misc.favset_num']; $i++) { if (!isset($_POST["{$setlist_name}_titles"][$i])) { $setlist_titles[$setlist_name][$i] = ''; continue; } $newname = trim($_POST["{$setlist_name}_titles"][$i]); $newname = preg_replace('/\\r\\n\\t/', ' ', $newname); $newname = htmlspecialchars($newname, ENT_QUOTES); $setlist_titles[$setlist_name][$i] = $newname; } } } $newdata = serialize($setlist_titles); if (FileCtl::file_write_contents($_conf['expack.misc.favset_file'], $newdata) === FALSE) { P2Util::pushInfoHtml("<p>p2 error: {$_conf['expack.misc.favset_file']} にお気に入りセット設定を書き込めませんでした。"); return FALSE; } return TRUE; }
if ($rss instanceof XML_RSS) { $channelInfo = $rss->getChannelInfo(); if (is_array($channelInfo) && array_key_exists('title', $channelInfo)) { $site = mb_convert_encoding($channelInfo['title'], 'CP932', 'UTF-8,CP51932,CP932,ASCII'); } } } } // ログに記録する変数を最低限のサニタイズ $xml = preg_replace_callback('/\\s/', 'rawurlencode', $xml); $site = preg_replace('/\\s+/', ' ', $site); $site = p2h($site); // }}} // {{{ 読み込み // rss_pathファイルがなければ生成 FileCtl::make_datafile($_conf['expack.rss.setting_path']); // rss_path読み込み; $lines = FileCtl::file_read_lines($_conf['expack.rss.setting_path'], FILE_IGNORE_NEW_LINES); // }}} // {{{ 処理 // 最初に重複要素を消去 if ($lines) { $i = -1; unset($neolines); foreach ($lines as $l) { $i++; $lar = explode("\t", $l); if ($lar[1] == $xml) { // 重複回避 $before_line_num = $i; continue;
include P2_BASE_DIR . '/tgrepc.php'; } exit; } } else { if ($_conf['ktai']) { include P2_BASE_DIR . '/tgrepc.php'; } exit; } // }}} // {{{ リストを更新 if (!empty($_GET['query'])) { $purge = !empty($_GET['purge']); $query = preg_replace('/\\s+/', ' ', trim($_GET['query'])); FileCtl::make_datafile($list_file); $tgrep_list = FileCtl::file_read_lines($list_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($tgrep_list)) { $tgrep_list = array(); } if ($purge) { $tgrep_tmp_list = $tgrep_list; $tgrep_list = array(); foreach ($tgrep_tmp_list as $tgrep_tmp_query) { if ($tgrep_tmp_query != $query) { $tgrep_list[] = $tgrep_tmp_query; } } } else { array_unshift($tgrep_list, $query); }
/** * 最近読んだスレに記録する * * @param array $data_ar * @return boolean */ function _recRecent($data_ar) { global $_conf; $data_line = implode('<>', $data_ar); $host = $data_ar[10]; $key = $data_ar[1]; // 速報headlineは最近読んだスレに記録しないようにしてみる if ($host == 'headline.2ch.net') { return true; } if (false === FileCtl::make_datafile($_conf['recent_file'], $_conf['rct_perm'])) { return false; } $lines = file($_conf['recent_file']); $newlines = array(); // 最初に重複要素を削除しておく if (is_array($lines)) { foreach ($lines as $line) { $line = rtrim($line); $lar = explode('<>', $line); if ($lar[1] == $key) { continue; } // keyで重複回避 if (!$lar[1]) { continue; } // keyのないものは不正データ $newlines[] = $line; } } // 新規データ追加 array_unshift($newlines, $data_line); while (sizeof($newlines) > $_conf['rct_rec_num']) { array_pop($newlines); } // 書き込む if ($newlines) { $cont = ''; foreach ($newlines as $l) { $cont .= $l . "\n"; } if (false === FileCtl::filePutRename($_conf['recent_file'], $cont)) { $errmsg = sprintf('p2 error: %s(), FileCtl::filePutRename() failed.', __FUNCTION__); trigger_error($errmsg, E_USER_WARNING); return false; } } return true; }
ini_set('user_agent', $_conf['expack.user_agent']); } // }}} // {{{ デザイン設定 読込 $skin_name = $default_skin_name = 'conf_user_style'; $skin = P2_CONF_DIR . '/conf_user_style.inc.php'; if (!$_conf['ktai'] && $_conf['expack.skin.enabled']) { // 保存されているスキン名 $saved_skin_name = null; if (file_exists($_conf['expack.skin.setting_path'])) { $saved_skin_name = rtrim(file_get_contents($_conf['expack.skin.setting_path'])); if (!preg_match('/^[0-9A-Za-z_\\-]+$/', $saved_skin_name)) { $saved_skin_name = null; } } else { FileCtl::make_datafile($_conf['expack.skin.setting_path'], $_conf['expack.skin.setting_perm']); } // リクエストで指定されたスキン名 $new_skin_name = null; if (array_key_exists('skin', $_REQUEST) && is_string($_REQUEST['skin'])) { $new_skin_name = $_REQUEST['skin']; if (!preg_match('/^[0-9A-Za-z_\\-]+$/', $new_skin_name)) { $new_skin_name = null; } elseif ($new_skin_name != $saved_skin_name) { FileCtl::file_write_contents($_conf['expack.skin.setting_path'], $new_skin_name); } } // リクエストで指定された一時スキン名 $tmp_skin_name = null; if (array_key_exists('tmp_skin', $_REQUEST) && is_string($_REQUEST['tmp_skin'])) { $tmp_skin_name = $_REQUEST['tmp_skin'];
/** * ファイル内容を読み込んで編集のためのHTMLを表示する * * @return void */ function _printEditFileHtml($path, $encode) { global $_conf, $modori_url, $rows, $cols; $info_msg_ht = P2Util::getInfoHtml(); if ($path == '') { die('Error: path が指定されていません'); } $filename = basename($path); $ptitle = "Edit: " . $filename; if (false === FileCtl::make_datafile($path)) { die(sprintf("Error: cannot make file. ( %s )", hs($path))); } $cont = file_get_contents($path); if ($encode == 'EUC-JP') { $cont = mb_convert_encoding($cont, 'SJIS-win', 'eucJP-win'); } $cont_area_ht = htmlspecialchars($cont, ENT_QUOTES); $modori_url_ht = ''; if ($modori_url) { $modori_url_ht = sprintf('<p><a href="%s">Back</a></p>', hs($modori_url)); } ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> <title><?php eh($ptitle); ?> </title> </head> <body onLoad="top.document.title=self.document.title;"> <?php echo $modori_url_ht; ?> Edit: <?php eh($path); ?> <form action="<?php eh($_SERVER['SCRIPT_NAME']); ?> " method="post" accept-charset="<?php eh($_conf['accept_charset']); ?> "> <input type="hidden" name="detect_hint" value="◎◇"> <input type="hidden" name="path" value="<?php eh($path); ?> "> <input type="hidden" name="modori_url" value="<?php eh($modori_url); ?> "> <input type="hidden" name="encode" value="<?php eh($encode); ?> "> <input type="hidden" name="rows" value="<?php eh($rows); ?> "> <input type="hidden" name="cols" value="<?php eh($cols); ?> "> <input type="submit" name="submit" value="Save"> <?php echo $info_msg_ht; ?> <br> <textarea style="font-size:9pt;" id="filecont" name="filecont" rows="<?php eh($rows); ?> " cols="<?php eh($cols); ?> " wrap="off"><?php eh($cont); ?> </textarea> </form> </body></html> <?php }
<script type="text/javascript" src="js/yui/ygDDList.js?{$_conf['p2_version_id']}"></script> <script type="text/javascript" src="js/yui/ygDDPlayer.js?{$_conf['p2_version_id']}"></script> EOP; } $body_at = $_conf['ktai'] ? $_conf['k_colors'] : ' onload="top.document.title=self.document.title;"'; echo "</head><body{$body_at}>\n"; P2Util::printInfoHtml(); //================================================================ // メイン部分HTML表示 //================================================================ //================================================================ // お気に板 //================================================================ // favitaファイルがなければ生成 FileCtl::make_datafile($_conf['favita_brd']); // favita読み込み $lines = FileCtl::file_read_lines($_conf['favita_brd'], FILE_IGNORE_NEW_LINES); $okini_itas = array(); $i = 0; if (is_array($lines)) { foreach ($lines as $l) { if (preg_match("/^\t?(.+?)\t(.+?)\t(.+?)\$/", $l, $matches)) { $id = "li{$i}"; $okini_itas[$id]['itaj'] = $itaj = rtrim($matches[3]); $okini_itas[$id]['itaj_en'] = $itaj_en = UrlSafeBase64::encode($itaj); $okini_itas[$id]['host'] = $host = $matches[1]; $okini_itas[$id]['bbs'] = $bbs = $matches[2]; $okini_itas[$id]['itaj_view'] = p2h($itaj); $okini_itas[$id]['itaj_ht'] = "&itaj_en=" . $itaj_en; $okini_itas[$id]['value'] = StrCtl::toJavaScript("{$host}@{$bbs}@{$itaj_en}");
/** * スレッドあぼーんをオンオフする * * $set は、0(解除), 1(追加), 2(トグル) */ function settaborn($host, $bbs, $key, $set) { global $_conf, $title_msg, $info_msg; //================================================================== // key.idx 読み込む //================================================================== // idxfileのパスを求めて $idx_host_bbs_dir_s = P2Util::idxDirOfHostBbs($host, $bbs); $idxfile = $idx_host_bbs_dir_s . $key . '.idx'; // データがあるなら読み込む if ($lines = FileCtl::file_read_lines($idxfile, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); } //================================================================== // p2_threads_aborn.idxに書き込む //================================================================== // p2_threads_aborn.idx のパス取得 $taborn_idx = $idx_host_bbs_dir_s . 'p2_threads_aborn.idx'; // p2_threads_aborn.idx がなければ生成 FileCtl::make_datafile($taborn_idx); // p2_threads_aborn.idx 読み込み; $taborn_lines = FileCtl::file_read_lines($taborn_idx, FILE_IGNORE_NEW_LINES); $neolines = array(); $aborn_attayo = false; if ($taborn_lines) { foreach ($taborn_lines as $l) { $lar = explode('<>', $l); if ($lar[1] == $key) { $aborn_attayo = true; // 既にあぼーん中である if ($set == 0 or $set == 2) { $title_msg_pre = "+ あぼーん 解除しますた"; $info_msg_pre = "+ あぼーん 解除しますた"; } continue; } if (!$lar[1]) { continue; } // keyのないものは不正データ $neolines[] = $l; } } // 新規データ追加 if ($set == 1 or !$aborn_attayo && $set == 2) { $newdata = "{$data[0]}<>{$key}<><><><><><><><>"; $neolines ? array_unshift($neolines, $newdata) : ($neolines = array($newdata)); $title_msg_pre = "○ あぼーん しますた"; $info_msg_pre = "○ あぼーん しますた"; } // 書き込む $cont = ''; if (!empty($neolines)) { foreach ($neolines as $l) { $cont .= $l . "\n"; } } if (FileCtl::file_write_contents($taborn_idx, $cont) === false) { p2die('cannot write file.'); } $GLOBALS['title_msg'] = $title_msg_pre; $GLOBALS['info_msg'] = $info_msg_pre; return true; }
/** * お気にスレをセットする * * @param string $host * @param string $bbs * @param string $key * @param int|string $setfavita 0(解除), 1(追加), 2(トグル), top, up, down, bottom * @param string $ttitle * @param int|null $setnum * @return bool */ function setFav($host, $bbs, $key, $setfav, $ttitle = null, $setnum = null) { global $_conf; //================================================================== // key.idx //================================================================== // idxfileのパスを求めて $idxfile = P2Util::idxDirOfHostBbs($host, $bbs) . $key . '.idx'; // 板ディレクトリが無ければ作る // FileCtl::mkdirFor($idxfile); // 既にidxデータがあるなら読み込む if ($lines = FileCtl::file_read_lines($idxfile, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); if (is_string($ttitle) && strlen($ttitle)) { $data[0] = p2h($ttitle, false); } } // {{{ スレッド.idx 記録 if (($setfav == '0' || $setfav == '1') && $_conf['favlist_idx'] == $_conf['orig_favlist_idx']) { // お気にスレから外した結果、idxの意味がなくなれば削除する if ($setfav == '0' and !$data[3] && !$data[4] && $data[9] <= 1) { @unlink($idxfile); } else { $sar = array($data[0], $key, $data[2], $data[3], $data[4], $data[5], $setfav, $data[7], $data[8], $data[9], $data[10], $data[11], $data[12]); P2Util::recKeyIdx($idxfile, $sar); } } // }}} //================================================================== // favlist.idx //================================================================== if (!is_null($setnum) && $_conf['expack.misc.multi_favs']) { if (0 < $setnum && $setnum <= $_conf['expack.misc.favset_num']) { $favlist_idx = $_conf['pref_dir'] . sprintf('/p2_favlist%d.idx', $setnum); } else { $favlist_idx = $_conf['orig_favlist_idx']; } } else { $favlist_idx = $_conf['favlist_idx']; } // favlistファイルがなければ生成 FileCtl::make_datafile($favlist_idx); // favlist読み込み $favlines = FileCtl::file_read_lines($favlist_idx, FILE_IGNORE_NEW_LINES); //================================================ // 処理 //================================================ $neolines = array(); $before_line_num = 0; $was_set = false; // 最初に重複要素を削除しておく if (!empty($favlines)) { $i = -1; foreach ($favlines as $l) { $i++; $lar = explode('<>', $l); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット $was_set = true; continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } else { $neolines[] = $l; } } } if ($setfav == 2) { $setfav = $was_set ? 0 : 1; } // 記録データ設定 if ($setfav) { if (!function_exists('getSetPosLines')) { include P2_LIB_DIR . '/getsetposlines.inc.php'; } $newdata = "{$data[0]}<>{$key}<>{$data[2]}<>{$data[3]}<>{$data[4]}<>{$data[5]}<>1<>{$data[7]}<>{$data[8]}<>{$data[9]}<>{$host}<>{$bbs}"; $rec_lines = getSetPosLines($neolines, $newdata, $before_line_num, $setfav); } else { $rec_lines = $neolines; } $cont = ''; if (!empty($rec_lines)) { foreach ($rec_lines as $l) { $cont .= $l . "\n"; } } // 書き込む if (FileCtl::file_write_contents($favlist_idx, $cont) === false) { p2die('cannot write file.'); } //================================================ // お気にスレ共有 //================================================ if ($_conf['join_favrank'] && $_conf['favlist_idx'] == $_conf['orig_favlist_idx']) { if ($setfav == "0") { $act = "out"; } elseif ($setfav == "1") { $act = "add"; } else { return; } $itaj = P2Util::getItaName($host, $bbs); $post = array("host" => $host, "bbs" => $bbs, "key" => $key, "ttitle" => $data[0], "ita" => $itaj, "act" => $act); postFavRank($post); } return true; }
/** * p2_favita.brdのパスを取得する * * @param int|null $setnum * @return string */ function setFavItaGetBrdPath($setnum = null) { global $_conf; if (!is_null($setnum) && $_conf['expack.misc.multi_favs']) { if (0 < $setnum && $setnum <= $_conf['expack.misc.favset_num']) { $favita_brd = $_conf['pref_dir'] . sprintf('/p2_favita%d.brd', $setnum); } else { $favita_brd = $_conf['orig_favita_brd']; } } else { $favita_brd = $_conf['favita_brd']; } // p2_favita.brd ファイルがなければ生成 FileCtl::make_datafile($favita_brd, $_conf['favita_perm']); return $favita_brd; }
$new_login_pass = $_POST['form_new_login_pass']; // 入力チェック if (!preg_match('/^[0-9A-Za-z_]+$/', $new_login_pass)) { P2Util::pushInfoHtml("<p>rep2 error: {$p_str['password']}を半角英数字で入力して下さい。</p>"); } elseif ($new_login_pass != $_POST['form_new_login_pass2']) { P2Util::pushInfoHtml("<p>rep2 error: {$p_str['password']} と {$p_str['password']} (確認) が一致しませんでした。</p>"); // パスワード変更登録処理を行う } else { $crypted_login_pass = sha1($new_login_pass); $auth_user_cont = <<<EOP <?php \$rec_login_user_u = '{$_login->user_u}'; \$rec_login_pass_x = '{$crypted_login_pass}'; ?> EOP; FileCtl::make_datafile($_conf['auth_user_file'], $_conf['pass_perm']); // ファイルがなければ生成 $fp = @fopen($_conf['auth_user_file'], 'wb'); if (!$fp) { p2die("{$_conf['auth_user_file']} を保存できませんでした。認証ユーザ登録失敗。"); } flock($fp, LOCK_EX); fputs($fp, $auth_user_cont); flock($fp, LOCK_UN); fclose($fp); P2Util::pushInfoHtml('<p>○認証パスワードを変更登録しました</p>'); } } //==================================================== // 補助認証 //====================================================
/** * 新規ユーザを作成する */ public function makeUser($user_u, $pass) { global $_conf; $crypted_login_pass = sha1($pass); $auth_user_cont = <<<EOP <?php \$rec_login_user_u = '{$user_u}'; \$rec_login_pass_x = '{$crypted_login_pass}'; ?> EOP; FileCtl::make_datafile($_conf['auth_user_file'], $_conf['pass_perm']); // ファイルがなければ生成 if (FileCtl::file_write_contents($_conf['auth_user_file'], $auth_user_cont) === false) { p2die("{$_conf['auth_user_file']} を保存できませんでした。認証{$p_str['user']}登録失敗。"); } return true; }
/** * brdファイルを生成する * * @access public * @return string|false 成功したら生成したbrdファイルのパスを返す */ function makeBrdFile($cachefile) { global $_conf; $cont = ''; $data = file($cachefile); $this->setBrdMatch($cachefile); // パターンマッチ形式を登録 $this->setBrdList($data); // カテゴリーと板をセット if ($this->categories) { foreach ($this->categories as $cate) { if ($cate->num > 0) { $cont .= $cate->name . "\t0\n"; foreach ($cate->menuitas as $mita) { $cont .= "\t{$mita->host}\t{$mita->bbs}\t{$mita->itaj}\n"; } } } } if (!$cont) { // 2008/07/14 なぜここでこんな条件が必要だったのか不明。コメントアウトしてみる。 //if (strlen($GLOBALS['word']) > 0) { P2Util::pushInfoHtml(sprintf("<p>p2 error: %s から板メニューを生成することはできませんでした。</p>\n", hs($cachefile))); //} unlink($cachefile); return false; } $p2brdfile = BrdCtl::getP2BrdFile($cachefile); if (false === FileCtl::make_datafile($p2brdfile, $_conf['p2_perm'])) { return false; } if (false === FileCtl::filePutRename($p2brdfile, $cont)) { die(sprintf('p2 error: %s を更新できませんでした', hs($p2brdfile))); return false; } return $p2brdfile; }
// 検索結果キャッシュのガーベッジコレクション if (mt_rand(0, 99) == 0) { P2Util::garbageCollection($cache_options['cacheDir'], $cache_options['lifeTime'], 'cache_' . $cache_group_result); P2Util::garbageCollection($cache_options['cacheDir'], $cache_options['lifeTime'], 'cache_' . $cache_group_profile); } $errors = isset($search_result['errors']) ? $search_result['errors'] : null; $threads = isset($search_result['threads']) ? $search_result['threads'] : null; $profile = $search_profile['profile']; $modified = strtotime($search_profile['modified']); if ($errors) { $cache->remove($cache_id_result, $cache_group_result); $cache->remove($cache_id_profile, $cache_group_profile); } else { // 検索履歴を更新 if ($_conf['expack.tgrep.recent_num'] > 0) { FileCtl::make_datafile($_conf['expack.tgrep.recent_file'], $_conf['expack.tgrep.file_perm']); $tgrep_recent_list = FileCtl::file_read_lines($_conf['expack.tgrep.recent_file'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($tgrep_recent_list)) { $tgrep_recent_list = array(); } array_unshift($tgrep_recent_list, preg_replace('/[\\r\\n\\t]/', ' ', trim($_GET['Q']))); $tgrep_recent_list = array_unique($tgrep_recent_list); while (count($tgrep_recent_list) > $_conf['expack.tgrep.recent_num']) { array_pop($tgrep_recent_list); } $tgrep_recent_data = implode("\n", $tgrep_recent_list) . "\n"; if (FileCtl::file_write_contents($_conf['expack.tgrep.recent_file'], $tgrep_recent_data) === false) { p2die('cannot write file.'); } chmod($_conf['expack.tgrep.recent_file'], $_conf['p2_perm']); }
notSelToDef(); // ルールを適用する applyRules(); // ポストされた値 > 現在の値 > デフォルト値 の順で新しい設定を作成する $conf_save = array('.' => $_conf['p2version']); foreach ($conf_user_def as $k => $v) { if (array_key_exists($k, $_POST['conf_edit'])) { $conf_save[$k] = $_POST['conf_edit'][$k]; } elseif (array_key_exists($k, $_conf)) { $conf_save[$k] = $_conf[$k]; } else { $conf_save[$k] = $v; } } // シリアライズして保存 FileCtl::make_datafile($_conf['conf_user_file']); if (FileCtl::file_write_contents($_conf['conf_user_file'], serialize($conf_save)) === false) { P2Util::pushInfoHtml('<p>×設定を更新保存できませんでした</p>'); } else { P2Util::pushInfoHtml('<p>○設定を更新保存しました</p>'); // 変更があれば、内部データも更新しておく $_conf = array_merge($_conf, $conf_user_def, $conf_save); } unset($conf_save); // }}} // {{{ デフォルトに戻すボタンが押されていたら } elseif (!empty($_POST['submit_default'])) { if (file_exists($_conf['conf_user_file']) and unlink($_conf['conf_user_file'])) { P2Util::pushInfoHtml('<p>○設定をデフォルトに戻しました</p>'); // 変更があれば、内部データも更新しておく $_conf = array_merge($_conf, $conf_user_def);
/** * 2ch IDにログインする * * @access public * @return string|false 成功したら2ch SIDを返す */ function login2ch() { global $_conf; // 2ch●ID, PW設定を読み込む if ($array = P2Util::readIdPw2ch()) { list($login2chID, $login2chPW, $autoLogin2ch) = $array; } else { P2Util::pushInfoHtml('<p>p2 error: 2chログインのためのIDとパスワードを登録して下さい。[<a href="login2ch.php" target="subject">2chログイン管理</a>]</p>'); return false; } $auth2ch_url = 'https://2chv.tora3.net/futen.cgi'; $postf = "ID=" . $login2chID . "&PW=" . $login2chPW; // ここでurlencodeすると通らなくなるので注意 $x_2ch_ua = 'X-2ch-UA: ' . $_conf['p2uaname'] . '/' . $_conf['p2version']; $dolib2ch = 'DOLIB/1.00'; $tempfile = $_conf['pref_dir'] . "/p2temp.php"; // 念のためあらかじめtempファイルを除去しておく if (file_exists($tempfile)) { unlink($tempfile); } $curl_msg = ''; // まずはfsockopenでSSL接続する // ただしPHPコンパイル時にOpenSSLサポートが有効になっていないと利用できず、 // DSO版(openssl.{so,dll}等)ではエラーが出る。 // @see http://jp.php.net/manual/ja/function.fsockopen.php if ($_conf['precede_openssl']) { if (!extension_loaded('openssl')) { $curl_msg .= "「PHPのopenssl」は使えないようです"; } elseif (!($r = _getAuth2chWithOpenSSL($login2chID, $login2chPW, $auth2ch_url, $x_2ch_ua, $dolib2ch))) { $curl_msg .= "「PHPのopenssl」で実行失敗。"; } } if (empty($r)) { // コマンドCURL優先 if (empty($_conf['precede_phpcurl'])) { if (!($r = _getAuth2chWithCommandCurl($login2chID, $login2chPW, $tempfile, $auth2ch_url, $x_2ch_ua, $dolib2ch))) { $curl_msg .= "「systemのcurlコマンド」で実行失敗。"; if (!extension_loaded('curl')) { $curl_msg .= "「PHPのcurl」は使えないようです"; } elseif (!($r = _getAuth2chWithPhpCurl($tempfile, $auth2ch_url, $x_2ch_ua, $dolib2ch, $postf))) { $curl_msg .= "「PHPのcurl」で実行失敗。"; } } // PHP CURL優先 } else { if (!extension_loaded('curl')) { $curl_msg .= "「PHPのcurl」は使えないようです"; } elseif (!($r = _getAuth2chWithPhpCurl($tempfile, $auth2ch_url, $x_2ch_ua, $dolib2ch, $postf))) { $curl_msg .= "「PHPのcurl」で実行失敗。"; } if (empty($r)) { if (!($r = _getAuth2chWithCommandCurl($login2chID, $login2chPW, $tempfile, $auth2ch_url, $x_2ch_ua, $dolib2ch))) { $curl_msg .= "「systemのcurlコマンド」で実行失敗。"; } } } } // 接続失敗ならば if (empty($r)) { if (file_exists($_conf['idpw2ch_php'])) { unlink($_conf['idpw2ch_php']); } if (file_exists($_conf['sid2ch_php'])) { unlink($_conf['sid2ch_php']); } P2Util::pushInfoHtml('<p>p2 info: 2ちゃんねるへの●IDログインを行うには、systemでcurlコマンドが使用可能\であるか、PHPの<a href="http://www.php.net/manual/ja/ref.curl.php">CURL関数</a>が有効である必要があります。</p>'); P2Util::pushInfoHtml(sprintf('<p>p2 error: 2chログイン処理に失敗しました。%s</p>', hs($curl_msg))); return false; } // tempファイルはすぐに捨てる if (file_exists($tempfile)) { unlink($tempfile); } $r = rtrim($r); // 分解 if (preg_match('/SESSION-ID=(.+?):(.+)/', $r, $matches)) { $uaMona = $matches[1]; $SID2ch = $matches[1] . ':' . $matches[2]; } else { //error_log($r); if (file_exists($_conf['sid2ch_php'])) { unlink($_conf['sid2ch_php']); } P2Util::pushInfoHtml("<p>p2 error: 2ch●ログイン接続に失敗しました。</p>"); return false; } // 認証照合失敗なら if ($uaMona == 'ERROR') { file_exists($_conf['idpw2ch_php']) and unlink($_conf['idpw2ch_php']); file_exists($_conf['sid2ch_php']) and unlink($_conf['sid2ch_php']); P2Util::pushInfoHtml("<p>p2 error: 2ch●ログインのSESSION-IDの取得に失敗しました。IDとパスワードを確認の上、ログインし直して下さい。</p>"); return false; } //echo $r;// // SIDの記録保持 $cont = <<<EOP <?php \$uaMona = '{$uaMona}'; \$SID2ch = '{$SID2ch}'; ?> EOP; FileCtl::make_datafile($_conf['sid2ch_php'], $_conf['pass_perm']); if (false === file_put_contents($_conf['sid2ch_php'], $cont, LOCK_EX)) { P2Util::pushInfoHtml("<p>p2 Error: {$_conf['sid2ch_php']} を保存できませんでした。ログイン登録失敗。</p>"); return false; } return $SID2ch; }
/** * $subject_keys をシリアライズして保存する */ function saveSubjectKeys($subject_keys, $sb_keys_txt, $sb_keys_b_txt) { global $_conf; //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('saveSubjectKeys()'); //if (file_exists($sb_keys_b_txt)) { unlink($sb_keys_b_txt); } if (empty($_REQUEST['norefresh']) && !empty($subject_keys)) { if (file_exists($sb_keys_txt)) { FileCtl::make_datafile($sb_keys_b_txt); copy($sb_keys_txt, $sb_keys_b_txt); } else { FileCtl::make_datafile($sb_keys_txt); } if ($sb_keys_cont = serialize($subject_keys)) { if (FileCtl::file_write_contents($sb_keys_txt, $sb_keys_cont) === false) { p2die('cannot write file.'); } } } //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('saveSubjectKeys()'); return true; }
/** * データphp形式のファイルで、末尾にデータを追加する * * @static * @return boolean */ function putDataPhp($data_php, &$cont, $perm = 0606, $ncheck = false) { if ($cont === "") { return true; } $pre_quote = preg_quote(DataPhp::getPre()); $hip_quote = preg_quote(DataPhp::getHip()); $cont_esc = DataPhp::escapeDataPhp($cont); $old_cont = @file_get_contents($data_php); if ($old_cont) { // ファイルが、データphp形式以外の場合は、何もせずにfalseを返す if (!preg_match("/^\\s*<\\?php\\s\\/\\*/", $old_cont)) { trigger_error(__FUNCTION__ . '() file is broken.', E_USER_WARNING); return false; } $old_cut = preg_replace('{' . $hip_quote . '.*$}s', '', $old_cont); // 指定に応じて、古い内容の末尾が改行でなければ、改行を追加する if ($ncheck) { if (substr($old_cut, -1) != "\n") { $old_cut .= "\n"; } } $new_cont = $old_cut . $cont_esc . DataPhp::getHip(); // データ内容がまだなければ、新規データphp } else { $new_cont = DataPhp::getPre() . $cont_esc . DataPhp::getHip(); } FileCtl::make_datafile($data_php, $perm); if (false === file_put_contents($data_php, $new_cont, LOCK_EX)) { // die("Error: ファイルを更新できませんでした"); return false; } return true; }