============================================================================== gwbbs.cgi - メインシステム ============================================================================== 最終更新日:2003-01-14 14:05 ■概要 全てはここから始まる. ■環境設定 環境設定は CGI の差し替えを用意にするために,全て config.pl でまかなっ ています. これは require 命令で取り込まれますが,取り込み時のエラーチェックなど はしていません. ■各機能へのジャンプ 先頭部分で get_formdata サブルーチンでフォームデータを読み込み, $FORM{'mode'} により機能分岐を行っています. 掲示板のシステム初期化も,先頭部分でほぼ行われています. クライアントの情報ブッコ抜きなども,アクセスされた瞬間をねらうためにな るだけ先頭位置で実行させるのが好ましいです. $FORM{'mode'} で何も指定されなかったり,機能分岐から外れた場合は html サブルーチンに飛んで掲示板を構築した後に終了します. ■Cookie この掲示板は Cookie を使って未読の表示などを行っています. Gloriosa で使われている Cookie の書式は以下の通りです. Set-Cookie: COOKIE_NAME=name:XXX,email:XXX,url:XXX,lines:XXX, rmkey:XXX,newc:XXX,cookie_validity:XXX,gzip_support:XXX; expires=$date_gmt\n *1: 見やすいように改行を入れてあります *2: XXX は一意の文字列 COOKIE_NAME : クッキーの名前を指定します. name : 投稿者名 email : e-mail アドレス url : 投稿者の Web アドレス lines : 1ページあたりの表示件数 rmkey : 暗号化された削除キー newc : 現在までの最新記事番号 (未読マーク表示の際に必要) cookie_validity : クッキー保存日数 (単位:日) gzip_support : gzip 圧縮転送を行うかどうか (enable/disable) expires : クッキーの保存期間 (Cookie 仕様に基づく) ■ログファイル ログファイルは新しい物が一番上に来るような構造になっています. 1レコードは \n で終了し,書き込み内の改行は全て \r に統一されています. 1レコード内には投稿者名や書き込み内容など,複数の情報が収まっています. この情報はカンマ区切りの CSV 型式で保存されています.最近は,このカン マ区切りだと投稿内部で半角カンマが使えないという不具合があるので,半角 カンマを <> という記号で補おうかと考えています. -------------------------- 書込年月日,書き込み通し番号,レス元番号,書込者名,リモートホスト名, リモートアドレス,フォワードホスト名,フォワードホストアドレス, メールアドレス,Webページアドレス,書込,タイトル, 削除キー (不可逆性の暗号化処理済み) -------------------------- *1: 長すぎるので改行してあります 書き込み通し番号はずっとインクリメントされていきます. レス元番号は,レスの元記事がどの記事なのかを記録しているフィールドです. 番号はレス元の「書き込み通し番号」になります. リモートホスト名には,リモートホスト名の他に削除マークも含んでいます. このフィールドの先頭に * もしくは ** の文字が記述されていることで削除 記事と見なす,「論理削除」を行っています. * が1つの場合は投稿者本人が削除したもので,** と2つ連ねている場合は管 理者権限で削除されたものとしています. これは,掲示板の書き込みが,誰の手で削除が行われたのかを知るための仕様 です. Webページアドレスは,http:// を削除したものが格納されます.http:// は 掲示板構築時に補完されます. 書き込み内容は,書き込み本文の改行は \r で表現されています.掲示板構築 時には \r を
\n として変換しています. 削除キーは encode_passwd サブルーチンで暗号化されたものが格納されてい ます. 書き込みが存在するログファイルをダウンロード,またはアップロードする場 合は,かならずバイナリモードで実行してください. そうしないと改行コードが全て壊れてしまい,正常に動作しません. 使用されている変数は以下の通りです. -------------------------- $dnt:書込年月日 $nb :書き込み通し番号 $rnb:レス元番号 $wnm:書込者名 $rh :リモートホスト名 $rip:リモートアドレス $fh :フォワードホスト名 $fip:フォワードホストアドレス $mad:メールアドレス $wad:Webページアドレス $wd :書込 $sbj:タイトル $pswd:削除キー -------------------------- 通常はこの表記ですが,スレッド開始記事とレス記事の両方を使用する場合は, スレッド開始記事で使用する変数を $r_XXX としています.. ■データ保存 ログファイルなどのデータは全て $logdir に保存するようにしてください. こうすることにより,ログファイルが存在しないときに書き込み動作を行うと, パーミッションが 777 にしてあるはずなので,ファイルが自動生成されるよ うになりますし,後々のメンテナンスも楽になります. ■記事構築 記事の構築は,現段階ではメモリを結構食ってしまう仕様になっています. スレッド構築時は,スレッド開始記事のみを格納している「スレッド開始記事 配列変数」と,全記事を格納している「記事配列変数」のそれぞれに記事を格 納しています. それを,スレッド開始記事配列変数をマスターループ,記事配列変数をサブル ープとし,マスターループの書き込み通し番号と,サブループのレス元番号が 一致したときにその一致した記事を HTML として構築してゆく,という手法を 取っています. 詳しくは以下のフローをご覧下さい. --------------------------- ログファイルを配列変数に全て読み込む ↓ ヘッダ構築 ↓ 配列変数を 1つずつサーチ <--+ ↓ | レス元番号がない?-- NO -----+ ↓YES | @ROOT に追加 ----------------+ ループ終了 ↓ マスターループ(@ROOT) ↓ スレッド開始記事構築 ↓ サブループ(@LOG) <---------------------+ ↓ | マスターループの記事通し番号と -- NO --+ サブループのレス元番号が同じ? | ↓YES | レス記事構築 --------------------------+ マスターループ終了 ↓ フッタ構築 ↓ 終了 --------------------------- ■外部スクリプト Gloriosaは外部スクリプトを取り込むことにより機能拡張を行えますが,これ はやはり本体にも手を入れないと使えません. 理想は外部スクリプトのみで内部にもアクセスできるようなスクリプトが良い のですが,プラグインのように便利には行かないところがちょっとアレです. (汗) # ここらへんはプラグインディレクトリに入っているファイルを全部インプリ メントするという手法で行うよう改善予定です. さて,その外部スクリプトの取り込みですが,通常は最初にまとめて行うよう になっています. 外部スクリプトは requrie 命令で取り込むようになっていますが,それをま とめて行っているサブルーチンは implement_subscript という場所です. 以下がその書式です. -------------------------- # 外部スクリプトを取り込む 1: $XXX_fname = 'XXX'; 2: $XXX_file = "$pl_dir$XXX_fname"; 3: $XXX_flag = eval("require \"$XXX_file\";"); 4: if ($XXX_flag) { $XXX_req_stat = '組込済み'; } 5: else { if (-f $XXX_file) { $XXX_req_stat = 'エラー'; } 6: else { $XXX_req_stat = '未使用'; } } -------------------------- *1 数字: は便宜上付けている行番号. *2 XXX は外部スクリプト制作者が用意した外部スクリプトのファイル名部分 (*.pl の * の部分) を使用するのがセオリー. 1行ずつ順に追っていきましょう. まず,1行目は制作者が用意した外部スクリプトのファイル名のみを変数に格 納しています. 2行目は外部スクリプトへのフルパスを格納しています. 2行にわけてあるのは,見た目の混乱を避けるタメなのであまり意味はありま せんが,見た目がいいのでこちらを採用して下さい. 3行目は外部スクリプトのインプリメントに成功したかどうかのフラグ保存コ ードです. このフラグを使って,現在外部スクリプトがインプリメントされているかどう かを判断します. 4行目から 6行目は,外部スクリプト「systeminfo.pl」で使用しています. もしシステムインフォメーションであなたが用意した外部スクリプトのインプ リメント情報を表示したい場合はここも書き換え,systeminfo.pl の特定の行 も追記しなければなりません. ■各サブルーチンの仕様 ・get_formdata フォームから投稿された POST もしくは GET 情報を連想配列に格納 します. 書式: &get_formdata; 普通にサブルーチンを呼び出すだけで,環境変数から情報を取り出し, $FORM{''} に格納します. チェックボックスなどで,同じ NAME 属性を持ったフォーム情報を投 稿した場合は,半角カンマで情報が結合されるようになっています. 他にも,フォームデータを分割するときに,特殊文字は変換される仕 組みになっています. どのような文字列が変換されるかはこのサブルーチンを直接見てくだ さい. ・load_logfile ログファイルを読み込み,配列変数に格納します. 書式: &load_logfile; 読み込まれた情報は @DATA に格納されます. ・save_logfile 投稿された投稿文をログファイルに保存します. 書式: &save_logfile; 投稿文はあらかじめ @SAVEDATA に全投稿内容を格納しておかなけれ ばなりません. ・ttoo_chars 全角の特定の文字を半角に変換します. 書式: &ttoo_chars(CHARS); CHARS には変換したい文字列を入れます. 変換された文字は $wd_cnv に格納されます. どのような文字が変換されるかは,ttoo_chars サブルーチンの $from_cnv をご覧下さい. ----------------------- 例) 全角を半角にする $chars = 'ABCDEFG'; &ttoo_chars($chars); print $wd_cnv; ----------------------- これ以外にもサブルーチンはありますが,システム固有のルーチンなので使用 しないでください.