Ejemplo n.º 1
0
 /**
  * SETTING.TXT をダウンロードして、パースして、キャッシュする
  *
  * @access  public
  * @return  true|null|false  成功|更新なし(キャッシュ)|失敗
  */
 function downloadSettingTxt()
 {
     global $_conf;
     $perm = $_conf['dl_perm'] ? $_conf['dl_perm'] : 0606;
     FileCtl::mkdirFor($this->setting_txt);
     // 板ディレクトリが無ければ作る
     $modified = null;
     if (file_exists($this->setting_srd) && file_exists($this->setting_txt)) {
         // 更新しない場合は、その場で抜けてしまう
         if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) {
             return null;
             // キャッシュが新しい場合も抜ける
         } elseif ($this->isSettingSrdCacheFresh()) {
             return null;
         }
         $modified = gmdate('D, d M Y H:i:s', filemtime($this->setting_txt)) . ' GMT';
     }
     // DL
     /*
     // PHP5
     if (!class_exists('HTTP_Request', false)) {
         require 'HTTP/Request.php';
     }
     */
     require_once 'HTTP/Request.php';
     $params = array();
     $params['timeout'] = $_conf['fsockopen_time_limit'];
     if ($_conf['proxy_use']) {
         $params['proxy_host'] = $_conf['proxy_host'];
         $params['proxy_port'] = $_conf['proxy_port'];
     }
     $req = new HTTP_Request($this->url, $params);
     $modified && $req->addHeader('If-Modified-Since', $modified);
     $req->addHeader('User-Agent', 'Monazilla/1.00 (' . $_conf['p2uaname'] . '/' . $_conf['p2version'] . ')');
     $response = $req->sendRequest();
     $error_msg = null;
     if (PEAR::isError($response)) {
         $error_msg = $response->getMessage();
     } else {
         $code = $req->getResponseCode();
         if ($code == 302) {
             // ホストの移転を追跡
             require_once P2_LIB_DIR . '/BbsMap.php';
             $new_host = BbsMap::getCurrentHost($this->host, $this->bbs);
             if ($new_host != $this->host) {
                 $aNewSettingTxt = new SettingTxt($new_host, $this->bbs);
                 return $aNewSettingTxt->downloadSettingTxt();
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     // DLエラー
     if (strlen($error_msg)) {
         P2Util::pushInfoHtml(sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), P2View::tagA(P2Util::throughIme($this->url), hs($this->url), array('target' => $_conf['ext_win_target']))));
         touch($this->setting_txt);
         // DL失敗した場合(404)も touch する
         touch($this->setting_srd);
         return false;
     }
     $body = $req->getResponseBody();
     // DL成功して かつ 更新されていたら保存
     if ($body && $code != 304) {
         // したらば or be.2ch.net ならEUCをSJISに変換
         if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) {
             $body = mb_convert_encoding($body, 'SJIS-win', 'eucJP-win');
         }
         if (false === FileCtl::filePutRename($this->setting_txt, $body)) {
             die('Error: cannot write file');
         }
         chmod($this->setting_txt, $perm);
         // パースして
         if (!$this->setSettingArrayFromSettingTxt()) {
             return false;
         }
         // srd保存する
         if (!$this->saveSettingSrd($this->setting_array)) {
             return false;
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         touch($this->setting_txt);
         // 同時にキャッシュもtouchしないと、setting_txtとsetting_srdで更新時間がずれて、
         // 毎回ここまで処理が来る(サーバへのヘッダリクエストが飛ぶ)場合がある。
         touch($this->setting_srd);
     }
     return true;
 }
Ejemplo n.º 2
0
/**
 * スレタイ(と本文)でマッチしたらtrueを返す
 */
function matchSbFilter(Thread $aThread)
{
    // 全文検索でdatがあれば、内容を読み込む
    if (!empty($_REQUEST['find_cont'])) {
        if (file_exists($aThread->keydat)) {
            $subject = file_get_contents($aThread->keydat);
            // be.2ch.net はEUC
            if (P2Util::isHostBe2chNet($aThread->host)) {
                $subject = mb_convert_encoding($subject, 'CP932', 'CP51932');
            }
        } else {
            return false;
        }
    } else {
        $subject = $aThread->ttitle;
    }
    if ($GLOBALS['sb_filter']['method'] == 'and') {
        foreach ($GLOBALS['words_fm'] as $word) {
            if (!StrCtl::filterMatch($word, $subject)) {
                return false;
            }
        }
    } else {
        if (!StrCtl::filterMatch($GLOBALS['word_fm'], $subject)) {
            return false;
        }
    }
    return true;
}
Ejemplo n.º 3
0
 /**
  * subject.txtを一括ダウンロード&保存する
  *
  * @param array|string $subjects
  * @param bool $force
  * @return void
  */
 public static function fetchSubjectTxt($subjects, $force = false)
 {
     global $_conf;
     // {{{ ダウンロード対象を設定
     // お気に板等の.idx形式のファイルをパース
     if (is_string($subjects)) {
         $lines = FileCtl::file_read_lines($subjects, FILE_IGNORE_NEW_LINES);
         if (!$lines) {
             return;
         }
         $subjects = array();
         foreach ($lines as $l) {
             $la = explode('<>', $l);
             if (count($la) < 12) {
                 continue;
             }
             $host = $la[10];
             $bbs = $la[11];
             if ($host === '' || $bbs === '') {
                 continue;
             }
             $id = $host . '<>' . $bbs;
             if (isset($subjects[$id])) {
                 continue;
             }
             $subjects[$id] = array($host, $bbs);
         }
         // [host, bbs] の連想配列を検証
     } elseif (is_array($subjects)) {
         $originals = $subjects;
         $subjects = array();
         foreach ($originals as $s) {
             if (!is_array($s) || !isset($s['host']) || !isset($s['bbs'])) {
                 continue;
             }
             $id = $s['host'] . '<>' . $s['bbs'];
             if (isset($subjects[$id])) {
                 continue;
             }
             $subjects[$id] = array($s['host'], $s['bbs']);
         }
         // 上記以外
     } else {
         return;
     }
     if (!count($subjects)) {
         return;
     }
     // }}}
     // {{{ キューをセットアップ
     // キューおよびその他の変数を初期化
     $queue = new P2HttpRequestQueue();
     $hosts = array();
     $time = time() - $_conf['sb_dl_interval'];
     $eucjp2sjis = null;
     // 各subject.txtへのリクエストをキューに追加
     foreach ($subjects as $subject) {
         list($host, $bbs) = $subject;
         $file = P2Util::datDirOfHostBbs($host, $bbs) . 'subject.txt';
         if (!$force && file_exists($file) && filemtime($file) > $time) {
             continue;
         }
         $url = 'http://' . $host . '/' . $bbs . '/subject.txt';
         if (P2Util::isHostJbbsShitaraba($host) || P2Util::isHostBe2chNet($host)) {
             if ($eucjp2sjis === null) {
                 $eucjp2sjis = new P2HttpCallback_SaveEucjpAsSjis();
             }
             $req = new P2HttpGet($url, $file, null, $eucjp2sjis);
         } else {
             $req = new P2HttpGet($url, $file);
         }
         // 同一ホストに対しての同時接続は MAX_REQUESTS_PER_HOST まで
         if (!isset($hosts[$host])) {
             $hosts[$host] = new P2HttpRequestQueue();
             $queue->push($req);
         } elseif (count($hosts[$host]) < self::MAX_REQUESTS_PER_HOST) {
             $queue->push($req);
         } else {
             $hosts[$host]->pop()->setNext($req);
         }
         $hosts[$host]->push($req);
     }
     // }}}
     // リクエストを送信
     if (count($queue)) {
         self::send(new HttpRequestPool(), $queue);
         clearstatcache();
     }
 }
Ejemplo n.º 4
0
Archivo: Thread.php Proyecto: poppen/p2
 /**
  * スレタイトルを取得セットする
  *
  * @access  public
  * @return  string
  */
 function setTitleFromLocal()
 {
     if (isset($this->ttitle)) {
         return $this->ttitle;
     }
     $this->ttitle = null;
     if (!empty($this->datlines)) {
         $firstdatline = rtrim($this->datlines[0]);
         $d = $this->explodeDatLine($firstdatline);
         $this->setTtitle($d[4]);
         // ローカルdatの1行目から取得
     } elseif (is_readable($this->keydat) and $fp = fopen($this->keydat, "rb")) {
         $l = fgets($fp, 32800);
         fclose($fp);
         $firstdatline = rtrim($l);
         if (strstr($firstdatline, "<>")) {
             $datline_sepa = "<>";
         } else {
             $datline_sepa = ",";
             $this->dat_type = "2ch_old";
         }
         $d = explode($datline_sepa, $firstdatline);
         $this->setTtitle($d[4]);
         // be.2ch.net ならEUC→SJIS変換
         if (P2Util::isHostBe2chNet($this->host)) {
             $ttitle = mb_convert_encoding($this->ttitle, 'SJIS-win', 'eucJP-win');
             $this->setTtitle($ttitle);
         }
     }
     return $this->ttitle;
 }
Ejemplo n.º 5
0
 /**
  * Datを読み込む
  * $this->datlines を set する
  *
  * @access  public
  * @return  boolean  実行成否
  */
 function readDat()
 {
     global $_conf;
     if (!file_exists($this->keydat)) {
         return false;
     }
     if ($this->datlines = file($this->keydat)) {
         // be.2ch.net ならEUC→SJIS変換
         // 念のためSJISとUTF-8も文字コード判定の候補に入れておく
         // ・・・が、文字化けしたタイトルのスレッドで誤判定があったので、指定しておく
         if (P2Util::isHostBe2chNet($this->host)) {
             //mb_convert_variables('SJIS-win', 'eucJP-win,SJIS-win,UTF-8', $this->datlines);
             mb_convert_variables('SJIS-win', 'eucJP-win', $this->datlines);
         }
         if (!strstr($this->datlines[0], '<>')) {
             $this->dat_type = '2ch_old';
         }
     }
     $this->rescount = sizeof($this->datlines);
     return true;
 }
Ejemplo n.º 6
0
 /**
  * スレタイトル取得メソッド
  */
 public function setTitleFromLocal()
 {
     if (!isset($this->ttitle)) {
         if ($this->datlines) {
             $firstdatline = rtrim($this->datlines[0]);
             $d = $this->explodeDatLine($firstdatline);
             $this->setTtitle($d[4]);
             // ローカルdatの1行目から取得
         } elseif (is_readable($this->keydat)) {
             $fd = fopen($this->keydat, "rb");
             $l = fgets($fd, 32800);
             fclose($fd);
             $firstdatline = rtrim($l);
             if (strpos($firstdatline, '<>') !== false) {
                 $datline_sepa = "<>";
             } else {
                 $datline_sepa = ",";
                 $this->dat_type = "2ch_old";
             }
             $d = explode($datline_sepa, $firstdatline);
             $this->setTtitle($d[4]);
             // be.2ch.net ならEUC→SJIS変換
             if (P2Util::isHostBe2chNet($this->host)) {
                 $ttitle = mb_convert_encoding($this->ttitle, 'CP932', 'CP51932');
                 $this->setTtitle($ttitle);
             }
         }
     }
     return $this->ttitle;
 }
Ejemplo n.º 7
0
 /**
  * SETTING.TXT をダウンロードして、パースして、キャッシュする
  *
  * @return boolean 実行成否
  */
 public function downloadSettingTxt()
 {
     global $_conf;
     // まちBBS・したらば は SETTING.TXT が存在しないものとする
     if (P2Util::isHostMachiBbs($this->_host) || P2Util::isHostJbbsShitaraba($this->_host)) {
         return false;
     }
     FileCtl::mkdirFor($this->_setting_txt);
     // 板ディレクトリが無ければ作る
     if (file_exists($this->_setting_srd) && file_exists($this->_setting_txt)) {
         // 更新しない場合は、その場で抜けてしまう
         if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) {
             return true;
             // キャッシュが新しい場合も抜ける
         } elseif ($this->isCacheFresh()) {
             return true;
         }
         $modified = http_date(filemtime($this->_setting_txt));
     } else {
         $modified = false;
     }
     // DL
     $params = array();
     $params['timeout'] = $_conf['http_conn_timeout'];
     $params['readTimeout'] = array($_conf['http_read_timeout'], 0);
     if ($_conf['proxy_use']) {
         $params['proxy_host'] = $_conf['proxy_host'];
         $params['proxy_port'] = $_conf['proxy_port'];
     }
     $req = new HTTP_Request($this->_url, $params);
     $modified && $req->addHeader('If-Modified-Since', $modified);
     $req->addHeader('User-Agent', "Monazilla/1.00 ({$_conf['p2ua']})");
     $response = $req->sendRequest();
     if (PEAR::isError($response)) {
         $error_msg = $response->getMessage();
     } else {
         $code = $req->getResponseCode();
         if ($code == 302) {
             // ホストの移転を追跡
             $new_host = BbsMap::getCurrentHost($this->_host, $this->_bbs);
             if ($new_host != $this->_host) {
                 $aNewSettingTxt = new SettingTxt($new_host, $this->_bbs);
                 $body = $aNewSettingTxt->downloadSettingTxt();
                 return true;
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     // DLエラー
     if (isset($error_msg) && strlen($error_msg) > 0) {
         $url_t = P2Util::throughIme($this->_url);
         $info_msg_ht = "<p class=\"info-msg\">Error: {$error_msg}<br>";
         $info_msg_ht .= "rep2 info: <a href=\"{$url_t}\"{$_conf['ext_win_target_at']}>{$this->_url}</a> に接続できませんでした。</p>";
         P2Util::pushInfoHtml($info_msg_ht);
         touch($this->_setting_txt);
         // DL失敗した場合も touch
         return false;
     }
     $body = $req->getResponseBody();
     // DL成功して かつ 更新されていたら保存
     if ($body && $code != '304') {
         // したらば or be.2ch.net ならEUCをSJISに変換
         if (P2Util::isHostJbbsShitaraba($this->_host) || P2Util::isHostBe2chNet($this->_host)) {
             $body = mb_convert_encoding($body, 'CP932', 'CP51932');
         }
         if (FileCtl::file_write_contents($this->_setting_txt, $body) === false) {
             p2die('cannot write file');
         }
         // パースしてキャッシュを保存する
         if (!$this->cacheParsedSettingTxt()) {
             return false;
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         touch($this->_setting_txt);
         // 同時にキャッシュもtouchしないと、_setting_txtと_setting_srdで更新時間がずれ、
         // 毎回ここまで処理が来る(サーバへのヘッダリクエストが飛ぶ)場合がある。
         touch($this->_setting_srd);
     }
     return true;
 }
Ejemplo n.º 8
0
/**
 * スレタイ(と本文)でマッチしたらtrueを返す
 *
 * @return  boolean
 */
function matchSbFilter(&$aThread)
{
    // 全文検索でdatがあれば、内容を読み込む
    if (!empty($_REQUEST['find_cont']) && file_exists($aThread->keydat)) {
        $dat_cont = file_get_contents($aThread->keydat);
    }
    if ($GLOBALS['sb_filter']['method'] == "and") {
        reset($GLOBALS['words_fm']);
        foreach ($GLOBALS['words_fm'] as $word_fm_ao) {
            // 全文検索でdatがあれば、内容を検索
            if (!empty($_REQUEST['find_cont']) && file_exists($aThread->keydat)) {
                // be.2ch.net はEUC
                if (P2Util::isHostBe2chNet($aThread->host)) {
                    $target_cont = mb_convert_encoding($word_fm_ao, 'eucJP-win', 'SJIS-win');
                }
                if (!StrCtl::filterMatch($target_cont, $dat_cont)) {
                    return false;
                }
                // スレタイを検索
            } elseif (!StrCtl::filterMatch($word_fm_ao, $aThread->ttitle)) {
                return false;
            }
        }
    } else {
        // 全文検索でdatがあれば、内容を検索
        if (!empty($_REQUEST['find_cont']) && file_exists($aThread->keydat)) {
            $target_cont = $GLOBALS['word_fm'];
            // be.2ch.net はEUC
            if (P2Util::isHostBe2chNet($aThread->host)) {
                $target_cont = mb_convert_encoding($target_cont, 'eucJP-win', 'SJIS-win');
            }
            if (!StrCtl::filterMatch($target_cont, $dat_cont)) {
                return false;
            }
            // スレタイだけ検索
        } elseif (!StrCtl::filterMatch($GLOBALS['word_fm'], $aThread->ttitle)) {
            return false;
        }
    }
    return true;
}
Ejemplo n.º 9
0
Archivo: post.php Proyecto: poppen/p2
/**
 * レスを書き込む or 新規スレッドを立てる
 * スレ立ての場合は、$key は空 '' でよい
 *
 * @return  boolean|string  書き込み成功なら true、失敗なら false または失敗理由文字列
 */
function _postIt($host, $bbs, $key, $post, $bbs_cgi)
{
    global $_conf, $popup, $rescount, $ttitle_en, $STYLE, $post_cache;
    list($request, $send_host, $send_port) = _buildRequestForPost($host, $bbs, $key, $post, $bbs_cgi);
    $maru_kakiko = empty($_POST['maru_kakiko']) ? 0 : 1;
    P2Util::setConfUser('maru_kakiko', $maru_kakiko);
    // 書き込みを一時的に保存
    $failed_post_file = P2Util::getFailedPostFilePath($host, $bbs, $key);
    $cont = serialize($post_cache);
    if (!DataPhp::writeDataPhp($failed_post_file, $cont, $_conf['res_write_perm'])) {
        p2die('ファイルの書き込みエラー');
    }
    // p2 sambaのチェック
    if ($p2SambaErrorMsgHtml = _getP2SambaErrorMsgHtml($host, $bbs)) {
        _showPostMsg(false, $p2SambaErrorMsgHtml, false);
        return false;
    }
    // WEBサーバへ接続
    $fp = fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']);
    if (!$fp) {
        _showPostMsg(false, "サーバ接続エラー: {$errstr} ({$errno})<br>p2 Error: 板サーバへの接続に失敗しました", false);
        return false;
    }
    // HTTPリクエスト送信
    fwrite($fp, $request, strlen($request));
    $post_seikou = false;
    $p2cookies = _readCookieFile(_cachePathForCookieByHost($host));
    // header
    while (!feof($fp)) {
        $l = fgets($fp, 8192);
        // クッキーキタ
        if (preg_match("/Set-Cookie: (.+?)\r\n/", $l, $matches)) {
            $cgroups = explode(";", $matches[1]);
            if ($cgroups) {
                foreach ($cgroups as $v) {
                    if (preg_match("/(.+)=(.*)/", $v, $m)) {
                        $k = ltrim($m[1]);
                        if ($k != 'path') {
                            $p2cookies[$k] = $m[2];
                        }
                    }
                }
            }
            // 転送は書き込み成功と判断
        } elseif (preg_match("/^Location: /", $l, $matches)) {
            $post_seikou = true;
        }
        if ($l == "\r\n") {
            break;
        }
    }
    // クッキーをファイルに保存する
    _saveCookieFile($p2cookies, _cachePathForCookieByHost($host));
    // body
    $response = '';
    while (!feof($fp)) {
        $response .= fread($fp, 164000);
    }
    fclose($fp);
    // be.2ch.net or JBBSしたらば 文字コード変換 EUC→SJIS
    if (P2Util::isHostBe2chNet($host) || P2Util::isHostJbbsShitaraba($host)) {
        $response = mb_convert_encoding($response, 'SJIS-win', 'eucJP-win');
        //<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
        $response = preg_replace("{(<head>.*<META http-equiv=\"Content-Type\" content=\"text/html; charset=)EUC-JP(\">.*</head>)}is", "\$1Shift_JIS\$2", $response);
    }
    $kakikonda_match = "/<title>.*(書きこみました|■ 書き込みました ■|書き込み終了 - SubAll BBS).*<\\/title>/is";
    $cookie_kakunin_match = "/<!-- 2ch_X:cookie -->|<title>■ 書き込み確認 ■<\\/title>|>書き込み確認。</";
    if (eregi("(<.+>)", $response, $matches)) {
        $response = $matches[1];
    }
    // カキコミ成功
    if (preg_match($kakikonda_match, $response, $matches) or $post_seikou) {
        // クッキーの書き込み自動保存を消去する
        if (isset($_COOKIE['post_msg'])) {
            P2Util::unsetCookie('post_msg');
            // ドメイン指定なしも入れておこ
            setcookie('post_msg', '', time() - 3600);
        }
        $reload = empty($_POST['from_read_new']);
        _showPostMsg(true, '書きこみが終わりました。', $reload);
        // 投稿失敗記録があれば削除する
        if (file_exists($failed_post_file)) {
            unlink($failed_post_file);
        }
        return true;
        //$response_ht = htmlspecialchars($response, ENT_QUOTES);
        //echo "<pre>{$response_ht}</pre>";
        // ■cookie確認表示(post再チャレンジしてね)
    } elseif (preg_match($cookie_kakunin_match, $response, $matches)) {
        $htm['more_hidden_post'] = '';
        // p2用の追加キー
        $more_hidden_keys = array('newthread', 'submit_beres', 'from_read_new', 'maru_kakiko', 'csrfid', 'k', UA::getQueryKey());
        foreach ($more_hidden_keys as $hk) {
            if (isset($_POST[$hk])) {
                $htm['more_hidden_post'] .= sprintf('<input type="hidden" name="%s" value="%s">', hs($hk), hs($_POST[$hk])) . "\n";
            }
        }
        $form_pattern = '/<form method="?POST"? action="?\\.\\.\\/test\\/(sub)?bbs\\.cgi(?:\\?guid=ON)?"?>/i';
        $myname = basename($_SERVER['SCRIPT_NAME']);
        $host_hs = hs($host);
        $popup_hs = hs($popup);
        $rescount_hs = hs($rescount);
        $ttitle_en_hs = hs($ttitle_en);
        $form_replace = <<<EOFORM
<form method="POST" action="{$myname}?guid=ON" accept-charset="{$_conf['accept_charset']}">
    <input type="hidden" name="detect_hint" value="◎◇">
    <input type="hidden" name="host" value="{$host_hs}">
    <input type="hidden" name="popup" value="{$popup_hs}">
    <input type="hidden" name="rescount" value="{$rescount_hs}">
    <input type="hidden" name="ttitle_en" value="{$ttitle_en_hs}">
    <input type="hidden" name="sub" value="\$1">
    {$htm['more_hidden_post']}
EOFORM;
        $response = preg_replace($form_pattern, $form_replace, $response);
        $h_b = explode("</head>", $response);
        // HTMLプリント
        echo $h_b[0];
        if (!$_conf['ktai']) {
            P2View::printIncludeCssHtml('style');
            P2View::printIncludeCssHtml('post');
        }
        if ($popup) {
            $mado_okisa = explode(',', $STYLE['post_pop_size']);
            $mado_okisa_x = $mado_okisa[0];
            $mado_okisa_y = $mado_okisa[1] + 200;
            echo <<<EOSCRIPT
            <script language="JavaScript">
            <!--
                resizeTo({$mado_okisa_x},{$mado_okisa_y});
            // -->
            </script>
EOSCRIPT;
        }
        echo "</head>";
        echo $h_b[1];
        //return false;
        return 'COOKIE';
        // その他はレスポンスをそのまま表示(結果はエラーとしてfalseを返す)
    } else {
        $response = ereg_replace('こちらでリロードしてください。<a href="\\.\\./[a-z]+/index\\.html"> GO! </a><br>', "", $response);
        echo $response;
        return false;
    }
}
Ejemplo n.º 10
0
 /**
  * Datを読み込む
  * $this->datlines を set する
  */
 public function readDat()
 {
     global $_conf;
     if (file_exists($this->keydat)) {
         if ($this->datlines = FileCtl::file_read_lines($this->keydat)) {
             // be.2ch.net ならEUC→SJIS変換
             // 念のためSJISとUTF-8も文字コード判定の候補に入れておく
             // ・・・が、文字化けしたタイトルのスレッドで誤判定があったので、指定しておく
             if (P2Util::isHostBe2chNet($this->host)) {
                 //mb_convert_variables('CP932', 'CP51932,CP932,UTF-8', $this->datlines);
                 mb_convert_variables('CP932', 'CP51932', $this->datlines);
             }
             if (strpos($this->datlines[0], '<>') === false) {
                 $this->dat_type = "2ch_old";
             }
         }
     } else {
         return false;
     }
     $this->rescount = sizeof($this->datlines);
     if ($_conf['flex_idpopup'] || $_conf['ngaborn_chain'] || $_conf['ngaborn_frequent'] || $_conf['ktai'] && ($_conf['mobile.clip_unique_id'] || $_conf['mobile.underline_id'])) {
         $this->_setIdCount();
     }
     return true;
 }
Ejemplo n.º 11
0
Archivo: P2Util.php Proyecto: poppen/p2
 /**
  * bbs(板) が be.2ch なら true を返す
  *
  * @since   2006/07/27
  * @access  public
  * @return  boolean
  */
 function isBbsBe2chNet($host, $bbs)
 {
     if (P2Util::isHostBe2chNet($host)) {
         return true;
     }
     // [todo] bbs名で判断しているが、SETTING.TXT の BBS_BE_ID=1 で判断したほうがよいだろう
     $be_bbs = array('be', 'nandemo', 'argue');
     if (P2Util::isHost2ch($host) && in_array($bbs, $be_bbs)) {
         return true;
     }
     return false;
 }
Ejemplo n.º 12
0
 /**
  * subject.txtをダウンロードする
  *
  * @return string subject.txt の中身
  */
 public function downloadSubject()
 {
     global $_conf;
     if ($this->storage === 'file') {
         FileCtl::mkdirFor($this->subject_file);
         // 板ディレクトリが無ければ作る
         if (file_exists($this->subject_file)) {
             if (!empty($_REQUEST['norefresh']) || empty($_REQUEST['refresh']) && isset($_REQUEST['word'])) {
                 return;
                 // 更新しない場合は、その場で抜けてしまう
             } elseif (!empty($GLOBALS['expack.subject.multi-threaded-download.done'])) {
                 return;
                 // 並列ダウンロード済の場合も抜ける
             } elseif (empty($_POST['newthread']) and $this->isSubjectTxtFresh()) {
                 return;
                 // 新規スレ立て時でなく、更新が新しい場合も抜ける
             }
             $modified = http_date(filemtime($this->subject_file));
         } else {
             $modified = false;
         }
     }
     // DL
     $params = array();
     $params['timeout'] = $_conf['http_conn_timeout'];
     $params['readTimeout'] = array($_conf['http_read_timeout'], 0);
     if ($_conf['proxy_use']) {
         $params['proxy_host'] = $_conf['proxy_host'];
         $params['proxy_port'] = $_conf['proxy_port'];
     }
     $req = new HTTP_Request($this->subject_url, $params);
     $modified && $req->addHeader("If-Modified-Since", $modified);
     $req->addHeader('User-Agent', "Monazilla/1.00 ({$_conf['p2ua']})");
     $response = $req->sendRequest();
     if (PEAR::isError($response)) {
         $error_msg = $response->getMessage();
     } else {
         $code = $req->getResponseCode();
         if ($code == 302) {
             // ホストの移転を追跡
             $new_host = BbsMap::getCurrentHost($this->host, $this->bbs);
             if ($new_host != $this->host) {
                 $aNewSubjectTxt = new SubjectTxt($new_host, $this->bbs);
                 $body = $aNewSubjectTxt->downloadSubject();
                 return $body;
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     if (isset($error_msg) && strlen($error_msg) > 0) {
         $url_t = P2Util::throughIme($this->subject_url);
         $info_msg_ht = "<p class=\"info-msg\">Error: {$error_msg}<br>";
         $info_msg_ht .= "rep2 info: <a href=\"{$url_t}\"{$_conf['ext_win_target_at']}>{$this->subject_url}</a> に接続できませんでした。</p>";
         P2Util::pushInfoHtml($info_msg_ht);
         $body = '';
     } else {
         $body = $req->getResponseBody();
     }
     // ■ DL成功して かつ 更新されていたら
     if ($body && $code != "304") {
         // したらば or be.2ch.net ならEUCをSJISに変換
         if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) {
             $body = mb_convert_encoding($body, 'CP932', 'CP51932');
         }
         if (FileCtl::file_write_contents($this->subject_file, $body) === false) {
             p2die('cannot write file');
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         // (変更がないのに修正時間を更新するのは、少し気が進まないが、ここでは特に問題ないだろう)
         if ($this->storage === 'file') {
             touch($this->subject_file);
         }
     }
     return $body;
 }
Ejemplo n.º 13
0
/**
 * 公式p2でレスを書き込む
 *
 * @return boolean 書き込み成功なら true、失敗なら false
 */
function postIt2($host, $bbs, $key, $FROM, $mail, $MESSAGE)
{
    if (P2Util::isHostBe2chNet($host) || !empty($_REQUEST['beres'])) {
        $beRes = true;
    } else {
        $beRes = false;
    }
    try {
        $posted = P2Util::getP2Client()->post($host, $bbs, $key, $FROM, $mail, $MESSAGE, $beRes, $response);
    } catch (P2Exception $e) {
        p2die('公式p2ポスト失敗', $e->getMessage());
    }
    if ($posted) {
        $reload = empty($_POST['from_read_new']);
        showPostMsg(true, '書きこみが終わりました。', $reload);
    } else {
        $result_msg = '公式p2ポスト失敗</p>' . '<pre>' . htmlspecialchars($response['body'], ENT_QUOTES, 'Shift_JIS') . '</pre>' . '<p>-';
        showPostMsg(false, $result_msg, false);
    }
    return $posted;
}
Ejemplo n.º 14
0
/**
 * レスを書き込む or 新規スレッドを立てる
 * スレ立ての場合は、$key は空 '' でよい
 *
 * @return  boolean  書き込み成功なら true、失敗なら false
 */
function postIt($host, $bbs, $key, $post)
{
    global $_conf, $post_result, $post_error2ch, $popup, $rescount, $ttitle_en, $STYLE;
    global $bbs_cgi, $post_cache;
    $method = "POST";
    $bbs_cgi_url = "http://" . $host . $bbs_cgi;
    $purl = parse_url($bbs_cgi_url);
    if (isset($purl['query'])) {
        $purl['query'] = "?" . $purl['query'];
    } else {
        $purl['query'] = "";
    }
    // プロキシ
    if ($_conf['proxy_use']) {
        $send_host = $_conf['proxy_host'];
        $send_port = $_conf['proxy_port'];
        $send_path = $bbs_cgi_url;
    } else {
        $send_host = $purl['host'];
        $send_port = $purl['port'];
        $send_port = isset($purl['port']) ? $purl['port'] : null;
        $send_path = $purl['path'] . $purl['query'];
    }
    !$send_port and $send_port = 80;
    $request = $method . " " . $send_path . " HTTP/1.0" . "\r\n";
    $request .= "Host: " . $purl['host'] . "\r\n";
    $remote_host = P2Util::getRemoteHost($_SERVER['REMOTE_ADDR']);
    $add_user_info = '';
    //$add_user_info = "; p2-client-ip: {$_SERVER['REMOTE_ADDR']}";
    //$add_user_info .= "; p2-client-host: {$remote_host}";
    $request .= "User-Agent: Monazilla/1.00 (" . $_conf['p2name'] . "/" . $_conf['p2version'] . "{$add_user_info})" . "\r\n";
    $request .= 'Referer: http://' . $purl['host'] . '/' . "\r\n";
    // クライアントのIPを送信するp2独自のヘッダ
    $request .= "X-P2-Client-IP: " . $_SERVER['REMOTE_ADDR'] . "\r\n";
    $request .= "X-P2-Client-Host: " . $remote_host . "\r\n";
    // クッキー
    $cookies_to_send = "";
    // クッキーの読み込み
    $cookie_file = cachePathForCookie($host);
    $p2cookies = readCookieFile($cookie_file);
    if ($p2cookies) {
        foreach ($p2cookies as $cname => $cvalue) {
            if ($cname != 'expires') {
                $cookies_to_send .= " {$cname}={$cvalue};";
            }
        }
    }
    // be.2ch 認証クッキー
    // be板では自動Be書き込みを試みる
    if (P2Util::isBbsBe2chNet($host, $bbs) || !empty($_REQUEST['submit_beres'])) {
        $cookies_to_send .= ' MDMD=' . $_conf['be_2ch_code'] . ';';
        // be.2ch.netの認証コード(パスワードではない)
        $cookies_to_send .= ' DMDM=' . $_conf['be_2ch_mail'] . ';';
        // be.2ch.netの登録メールアドレス
    }
    !$cookies_to_send and $cookies_to_send = ' ;';
    $request .= 'Cookie:' . $cookies_to_send . "\r\n";
    //$request .= 'Cookie: PON='.$SPID.'; NAME='.$FROM.'; MAIL='.$mail."\r\n";
    $request .= "Connection: Close\r\n";
    // {{{ POSTの時はヘッダを追加して末尾にURLエンコードしたデータを添付
    if (strtoupper($method) == "POST") {
        $post_enc = array();
        while (list($name, $value) = each($post)) {
            if (!isset($value)) {
                continue;
            }
            // したらば or be.2ch.netなら、EUCに変換
            if (P2Util::isHostJbbsShitaraba($host) || P2Util::isHostBe2chNet($host)) {
                $value = mb_convert_encoding($value, 'eucJP-win', 'SJIS-win');
            }
            $post_enc[] = $name . "=" . urlencode($value);
        }
        $postdata = implode("&", $post_enc);
        $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $request .= "Content-Length: " . strlen($postdata) . "\r\n";
        $request .= "\r\n";
        $request .= $postdata;
    } else {
        $request .= "\r\n";
    }
    // }}}
    $maru_kakiko = empty($_POST['maru_kakiko']) ? 0 : 1;
    setConfUser('maru_kakiko', $maru_kakiko);
    // 書き込みを一時的に保存
    $failed_post_file = P2Util::getFailedPostFilePath($host, $bbs, $key);
    $cont = serialize($post_cache);
    DataPhp::writeDataPhp($failed_post_file, $cont, $_conf['res_write_perm']);
    // WEBサーバへ接続
    $fp = fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']);
    if (!$fp) {
        showPostMsg(false, "サーバ接続エラー: {$errstr} ({$errno})<br>p2 Error: 板サーバへの接続に失敗しました", false);
        return false;
    }
    // HTTPリクエスト送信
    fputs($fp, $request);
    $post_seikou = false;
    // header
    while (!feof($fp)) {
        $l = fgets($fp, 8192);
        // クッキーキタ
        if (preg_match("/Set-Cookie: (.+?)\r\n/", $l, $matches)) {
            //echo "<p>".$matches[0]."</p>"; //
            $cgroups = explode(";", $matches[1]);
            if ($cgroups) {
                foreach ($cgroups as $v) {
                    if (preg_match("/(.+)=(.*)/", $v, $m)) {
                        $k = ltrim($m[1]);
                        if ($k != "path") {
                            $p2cookies[$k] = $m[2];
                        }
                    }
                }
            }
            if ($p2cookies) {
                $cookies_to_send = '';
                foreach ($p2cookies as $cname => $cvalue) {
                    if ($cname != "expires") {
                        $cookies_to_send .= " {$cname}={$cvalue};";
                    }
                }
                $newcokkies = "Cookie:{$cookies_to_send}\r\n";
                $request = preg_replace("/Cookie: .*?\r\n/", $newcokkies, $request);
            }
            // 転送は書き込み成功と判断
        } elseif (preg_match("/^Location: /", $l, $matches)) {
            $post_seikou = true;
        }
        if ($l == "\r\n") {
            break;
        }
    }
    // クッキーをファイルに保存する
    saveCookieFile($p2cookies, $cookie_file);
    // body
    $response = '';
    while (!feof($fp)) {
        $response .= fread($fp, 164000);
    }
    fclose($fp);
    // be.2ch.net or JBBSしたらば 文字コード変換 EUC→SJIS
    if (P2Util::isHostBe2chNet($host) || P2Util::isHostJbbsShitaraba($host)) {
        $response = mb_convert_encoding($response, 'SJIS-win', 'eucJP-win');
        //<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
        $response = preg_replace("{(<head>.*<META http-equiv=\"Content-Type\" content=\"text/html; charset=)EUC-JP(\">.*</head>)}is", "\$1Shift_JIS\$2", $response);
    }
    $kakikonda_match = "/<title>.*(書きこみました|■ 書き込みました ■|書き込み終了 - SubAll BBS).*<\\/title>/is";
    $cookie_kakunin_match = "/<!-- 2ch_X:cookie -->|<title>■ 書き込み確認 ■<\\/title>|>書き込み確認。</";
    if (eregi("(<.+>)", $response, $matches)) {
        $response = $matches[1];
    }
    // カキコミ成功
    if (preg_match($kakikonda_match, $response, $matches) or $post_seikou) {
        // クッキーの書き込み自動保存を消去する
        isset($_COOKIE['post_msg']) and setcookie('post_msg', '', time() - 3600);
        $reload = empty($_POST['from_read_new']);
        showPostMsg(true, '書きこみが終わりました。', $reload);
        // 投稿失敗記録があれば削除する
        if (file_exists($failed_post_file)) {
            unlink($failed_post_file);
        }
        return true;
        //$response_ht = htmlspecialchars($response, ENT_QUOTES);
        //echo "<pre>{$response_ht}</pre>";
        // ■cookie確認(post再チャレンジ)
    } elseif (preg_match($cookie_kakunin_match, $response, $matches)) {
        $htm['more_hidden_post'] = '';
        $more_hidden_keys = array('newthread', 'submit_beres', 'from_read_new', 'maru_kakiko', 'csrfid', 'k', 'b');
        foreach ($more_hidden_keys as $hk) {
            if (isset($_POST[$hk])) {
                $value_hd = htmlspecialchars($_POST[$hk], ENT_QUOTES);
                $htm['more_hidden_post'] .= "<input type=\"hidden\" name=\"{$hk}\" value=\"{$value_hd}\">\n";
            }
        }
        $form_pattern = '/<form method=\\"?POST\\"? action=\\"?\\.\\.\\/test\\/(sub)?bbs\\.cgi(?:\\?guid=ON)?\\"?>/i';
        $myname = basename($_SERVER['SCRIPT_NAME']);
        $form_replace = <<<EOFORM
<form method="POST" action="{$myname}" accept-charset="{$_conf['accept_charset']}">
    <input type="hidden" name="detect_hint" value="◎◇">
    <input type="hidden" name="host" value="{$host}">
    <input type="hidden" name="popup" value="{$popup}">
    <input type="hidden" name="rescount" value="{$rescount}">
    <input type="hidden" name="ttitle_en" value="{$ttitle_en}">
    <input type="hidden" name="sub" value="\$1">
    {$htm['more_hidden_post']}
EOFORM;
        $response = preg_replace($form_pattern, $form_replace, $response);
        $h_b = explode("</head>", $response);
        // HTMLプリント
        echo $h_b[0];
        if (!$_conf['ktai']) {
            include_once './style/style_css.inc';
            include_once './style/post_css.inc';
        }
        if ($popup) {
            $mado_okisa = explode(',', $STYLE['post_pop_size']);
            $mado_okisa_x = $mado_okisa[0];
            $mado_okisa_y = $mado_okisa[1] + 200;
            echo <<<EOSCRIPT
            <script language="JavaScript">
            <!--
                resizeTo({$mado_okisa_x},{$mado_okisa_y});
            // -->
            </script>
EOSCRIPT;
        }
        echo "</head>";
        echo $h_b[1];
        return false;
        // その他はレスポンスをそのまま表示(結果はエラーとしてfalseを返す)
    } else {
        $response = ereg_replace('こちらでリロードしてください。<a href="\\.\\./[a-z]+/index\\.html"> GO! </a><br>', "", $response);
        echo $response;
        return false;
    }
}
Ejemplo n.º 15
0
 /**
  * subject.txtをダウンロードする
  *
  * @access  public
  * @return  array|null|false  subject.txtの配列データ(eaccelerator, apc用)、またはnullを返す。
  *                            失敗した場合はfalseを返す。
  */
 function downloadSubject()
 {
     global $_conf;
     static $spentDlTime_ = 0;
     // DL所要合計時間
     $perm = isset($_conf['dl_perm']) ? $_conf['dl_perm'] : 0606;
     $modified = false;
     if ($this->storage == 'file') {
         FileCtl::mkdirFor($this->subject_file);
         // 板ディレクトリが無ければ作る
         if (file_exists($this->subject_file)) {
             // ファイルキャッシュがあれば、DL制限時間をかける
             if (UA::isK()) {
                 $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTimeM'];
             } else {
                 $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTime'];
             }
             if ($dlSubjectTotalLimitTime and $spentDlTime_ > $dlSubjectTotalLimitTime) {
                 return null;
             }
             // 条件によって、キャッシュを適用する
             // subject.php でrefresh指定がある時は、キャッシュを適用しない
             if (!(basename($_SERVER['SCRIPT_NAME']) == $_conf['subject_php'] && !empty($_REQUEST['refresh']))) {
                 // キャッシュ適用指定時は、その場で抜ける
                 if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) {
                     return null;
                     // 並列ダウンロード済の場合も抜ける
                 } elseif (!empty($GLOBALS['expack.subject.multi-threaded-download.done'])) {
                     return null;
                     // 新規スレ立て時以外で、キャッシュが新鮮な場合も抜ける
                 } elseif (empty($_POST['newthread']) and $this->isSubjectTxtFresh()) {
                     return null;
                 }
             }
             $modified = gmdate("D, d M Y H:i:s", filemtime($this->subject_file)) . " GMT";
         }
     }
     $dlStartTime = $this->microtimeFloat();
     // DL
     require_once 'HTTP/Request.php';
     $params = array();
     $params['timeout'] = $_conf['fsockopen_time_limit'];
     if ($_conf['proxy_use']) {
         $params['proxy_host'] = $_conf['proxy_host'];
         $params['proxy_port'] = $_conf['proxy_port'];
     }
     $req = new HTTP_Request($this->subject_url, $params);
     $modified && $req->addHeader('If-Modified-Since', $modified);
     $req->addHeader('User-Agent', sprintf('Monazilla/1.00 (%s/%s)', $_conf['p2uaname'], $_conf['p2version']));
     $response = $req->sendRequest();
     $error_msg = null;
     if (PEAR::isError($response)) {
         $error_msg = $response->getMessage();
     } else {
         $code = $req->getResponseCode();
         if ($code == 302) {
             // ホストの移転を追跡
             require_once P2_LIB_DIR . '/BbsMap.php';
             $new_host = BbsMap::getCurrentHost($this->host, $this->bbs);
             if ($new_host != $this->host) {
                 $aNewSubjectTxt = new SubjectTxt($new_host, $this->bbs);
                 return $aNewSubjectTxt->downloadSubject();
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     if (!is_null($error_msg) && strlen($error_msg) > 0) {
         $attrs = array();
         if ($_conf['ext_win_target']) {
             $attrs['target'] = $_conf['ext_win_target'];
         }
         $atag = P2View::tagA(P2Util::throughIme($this->subject_url), hs($this->subject_url), $attrs);
         $msg_ht = sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), $atag);
         P2Util::pushInfoHtml($msg_ht);
         $body = '';
     } else {
         $body = $req->getResponseBody();
     }
     $dlEndTime = $this->microtimeFloat();
     $dlTime = $dlEndTime - $dlStartTime;
     $spentDlTime_ += $dlTime;
     // DL成功して かつ 更新されていたら
     if ($body && $code != '304') {
         // したらば or be.2ch.net ならEUCをSJISに変換
         if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) {
             $body = mb_convert_encoding($body, 'SJIS-win', 'eucJP-win');
         }
         // eaccelerator or apcに保存する場合
         if ($this->storage == 'eaccelerator' || $this->storage == 'apc') {
             $cache_key = "{$this->host}/{$this->bbs}";
             $cont = rtrim($body);
             $lines = explode("\n", $cont);
             if ($this->storage == 'eaccelerator') {
                 eaccelerator_lock($cache_key);
                 eaccelerator_put($cache_key, $lines, $_conf['sb_dl_interval']);
                 eaccelerator_unlock($cache_key);
             } else {
                 apc_store($cache_key, $lines, $_conf['sb_dl_interval']);
             }
             return $lines;
             // ファイルに保存する場合
         } else {
             if (false === FileCtl::filePutRename($this->subject_file, $body)) {
                 // 保存に失敗はしても、既存のキャッシュが読み込めるならよしとしておく
                 if (is_readable($this->subject_file)) {
                     return null;
                 } else {
                     die("Error: cannot write file");
                     return false;
                 }
             }
             chmod($this->subject_file, $perm);
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         // (変更がないのに修正時間を更新するのは、少し気が進まないが、ここでは特に問題ないだろう)
         if ($this->storage == 'file') {
             touch($this->subject_file);
         }
     }
     return null;
 }