bbs.cgi再開発プロジェクト6

このエントリーをはてなブックマークに追加
738▲ ◆cZfSunOs.U
実装済:
    subject.txt, subback.html, dat/*.dat 更新
    あぼーん
    dat/*.dat から subject.txt, subback.html 再生成
未実装:
    index.html, html/*.html 更新
    他板へのスレ移動 etc...

とりあえず↑ってところですが http://sunos.saita.ma/bbsd.c
全部実装すると雪だるま対応仕様になりますが,とりあえず今の段階でも
subject.txt 更新等の重い処理を bbs.cgi から抜き出して軽量化にはなると思います.

使用法: bbsd [-cfh] [-b bindaddr] [-d docroot] [-i subjects_interval] [-I setting_interval] [-n nthreads] [-p port] [-s servername]
    -b bindaddr: UDP ソケットを bind するアドレスを指定 [default: 127.0.0.1]
    -c: 入力のバイトシーケンスチェックを行う (環境変数 LANG/LC_CTYPE/LC_ALL に依存)
    -d docroot: httpd の document root [default: /usr/local/apache2/htdocs]
    -f: フォアグラウンドで実行
    -h: ヘルプ表示
    -i subjects_interval: subject.txt 等の更新間隔(秒) [default: 5]
    -I setting_interval: SETTING.TXT のチェック間隔(秒) [default: 60]
    -p port: UDP ソケットのポート番号 [default: 2222]
    -s servername: httpd のサーバ名 [default: www.example.com]

-DUSE_THREADS 付きでビルドするとマルチスレッド版になり,このオプションが追加.
    -n nthreads: worker スレッド数 [default: 4]

んで,例えばこんな感じで起動する,と.
    su ch2qb5 -c 'LANG=ja_JP.SJIS bbsd -c -d/home/ch2qb5/htdocs -sqb5.2ch.net'

bbs.cgi からの呼び出し法は
----------------------------------------------------------------------
use Socket;

use constant BBSD_HOST => inet_aton('127.0.0.1');
use constant BBSD_PORT => 2222;
use constant BBSD_TIMEOUT => 1;

sub bbsd {
    my ($rfd, $str) = ('', '');
    my $sin = sockaddr_in(BBSD_PORT, BBSD_HOST);
    socket(SOCK, AF_INET, SOCK_DGRAM, 0) || return "$!";
    send(SOCK, join('/', @_), 0, $sin) || return "$!";
    vec($rfd, fileno(SOCK), 1) = 1;
    if (select($rfd, undef, undef, BBSD_TIMEOUT)) {
        recv(SOCK, $str, 256, 0) || return "$!";
    }
    else {
        $str = "書き込みを受理しましたがサーバが混雑しています.書き込みが反映されない場合もあります.";
    }
    return $str;
}
----------------------------------------------------------------------
739▲ ◆cZfSunOs.U :2005/06/30(木) 23:47:02 ID:rETl+gr10
で,書き込み処理はこんな感じで.
    my $errmsg = bbsd($bbs, $key, $datline);
$bbs は板の指定(operate),$key はスレッドキー(1113117347),
$datline は *.dat への出力と同じ形式の文字列.
    name<>email<>date etc.<>message<>[title]
正常に処理されると $errmsg は空文字列で,エラーが発生した場合は
それを示す文字列になります.

この bbsd は subject データをオンメモリで保持するため,
他のプログラムが subject.txt 等を変更しても bbsd によって
上書きされてしまうので,あぼーんや subject 再生成等の機能も
搭載しました.

レスの通常あぼーん:
    my $errmsg = bbsd($bbs, "delete:$key", $range);
レスの透明あぼーん:
    my $errmsg = bbsd($bbs, "tdelete:$key", $range);
スレッドのゴミ箱逝き:
    my $errmsg = bbsd($bbs, "delete:$key", '*');
スレッドのファイル自体削除:
    my $errmsg = bbsd($bbs, "tdelete:$key", '*');

$range は例えば "2-19,22,24,26-29" のようなレス番指定.

subject.txt 等の再生成:
    my $errmsg = bbsd($bbs, 'repair');

この処理は時間がかかりそうなら BBSD_TIMEOUT はもっと長い方がいいかも知れません.
もっとも,UDP ソケットキューがあふれてリクエストが破棄されているとかでない限り
タイムアウトになっても処理自体は行われますが.