#!/usr/local/bin/perl
#↑Perlのパスをサーバに合わせて記述して下さい。
# ↓定義
#-----------------------------------------------------------------------------#
package appspage::resbbs::define;
my $define = {};
#【基本設定】
#-----------------------------------------------------------------------------#
# ■管理用パスワード(記号を除く半角英数)
$define->{'ADMIN_PASSW'} = '1234';
# ■ファイルロック方法
# '0' mkdir関数 / flock関数が使えないサーバ用
# '1' flock関数 / #標準
$define->{'LOCK_METHOD'} = '1';
# ※以上で基本的な設定は完了です。
#【プログラム情報】
#-----------------------------------------------------------------------------#
#
# 著作権表示を残していただける範囲内であれば、
# 商用、非商用問わず、無料でお使いいただけ、改造も自由です。
#
# (C) Apps Page.
# http://apps.cside.com/
#
$define->{'THIS_NAME'} = '第1期掲示板';
$define->{'VERSION'} = '1.11';
$define->{'LICENSE'} = 'FREE';
#【ファイル構成】
#-----------------------------------------------------------------------------#
#
#
# resbbs/ ……………………………… (755) プログラムディレクトリ
# │
# ├ index.cgi …………………… (755) 実行ファイル/このファイル
# │
# ├ data/ ………………………… (777) データ記録ディレクトリ
# │ └ 各データファイル ……… (666) 全て同じパーミッション
# │
# ├ lib/ ………………………… (755) ライブラリディレクトリ
# │ └ 各ライブラリファイル … (644) 全て同じパーミッション
# │
# └ lock/ ………………………… (777) ロックディレクトリ
# └ flock.cgi …………… (666) ロックファイル
#
#
#【セキュリティと設置環境設定】
#-----------------------------------------------------------------------------#
#
#
# 下記の設定項目で、セキュリティ強化や、設置環境特有の状態に変更できますが、
# 分からない場合、変更しない方が無難です。
#
#
# ■ロックディレクトリ(このファイルからのパス)
$define->{'LOCK_DIR'} = 'lock/';
# ■データ記録ディレクトリ(このファイルからのパス)
$define->{'DATA_DIR'} = 'data/';
# ■ライブラリディレクトリ(このファイルからのパス)
$define->{'LIB_DIR'} = 'lib/';
# ■作業用ディレクトリ(このファイルからのパス)
$define->{'TMP_DIR'} = 'data/';
# ■クッキー発行元パス(ウェブサーバルートパスからの記述)
# 例1:設置アドレスが、http://www.hoge.com/script/ の場合
# '/' → '/script/'
# 例2:設置アドレスが、http://www.hoge.com/~name/script/ の場合
# '/' → '/~name/script/'
$define->{'CK_PATH'} = '/';
# ■クッキーネーム(記号を除く半角英数)
# 複数設置する場合に、適当な名前を付けて区別できます。
# 例: 'resbbs' → 'resbbs2'
$define->{'CK_NAME'} = 'resbbs';
# ■クッキー有効日数(半角数字)
$define->{'CK_DAYS'} = '30';
# ■暗号化に使う文字列(半角英数2文字)
$define->{'SALT'} = 'PW';
# ■セッション変数発行に使う文字列(半角英数8文字まで)
$define->{'SESS_CHAR'} = 'SESSION';
# ■参照元アドレスによる一部機能のアクセス制限
# 例1:設置アドレスが、http://www.yourserver.com/script/ の場合
# '' → 'http://www.yourserver.com/'
# 例2:設置アドレスが、http://www.hoge.com/~name/script/ の場合
# '' → 'http://www.hoge.com/~name/'
$define->{'HTTP_REF'} = '';
# ■管理画面へのキー(記号を除く半角英数)
# 例: 'admin' → 'seclet' とした場合、
# 管理画面へのアドレスは
# http://設置アドレス/index.cgi?m=admin から、
# http://設置アドレス/index.cgi?m=seclet へ変更されます。
$define->{'ADMIN_KEY'} = 'admin';
# ■管理画面へのリンク('0'非表示 / '1'表示#標準)
# ※非表示にした場合、上記の"管理画面へのキー"を参考にアクセスして下さい。
$define->{'ADMIN_LINK'} = '1';
# ■jcode.plライブラリ('0'使わない / '1'使う#標準)
$define->{'JCODE'} = '1';
# ■suEXEC環境オプション('0'#標準 / '1' suEXEC環境限定)
# '0'#標準の場合、データファイルパーミッションは常に666です。
# '1'を設定した場合、更新時、元のパーミッションを引継ぐか、644です。
# ※分からない方、suEXEC環境でない方は、『絶対に』変更しないで下さい。
$define->{'SU_MODE'} = '0';
# ■flock関数がシステムコールへ渡す値(システムコールマニュアル参照)
# flock関数でファイルロックする場合のみ。
# 下記は最も一般的に使われる値です。
$define->{'LOCK_EX'} = 1;
$define->{'LOCK_SH'} = 2;
$define->{'LOCK_UN'} = 8;
#【広告挿入設定】
#-----------------------------------------------------------------------------#
#
#
# 画面上下にバナー広告など貼付ける場合にどうぞ。
#
#
# ■画面上の広告HTMLタグ
# 例1: '' → '
'
# 例2: '' → '
' など
$define->{'ADVERT_TOP'} = '';
# ■画面下の広告HTMLタグ
$define->{'ADVERT_BOTTOM'} = '';
#=============================================================================#
#
# これ以下は、変更の必要ありません。
#
#=============================================================================#
sub new { return bless $define; }
# ↓主なクラス
#-----------------------------------------------------------------------------#
package appspage::resbbs::main;
#use strict;
#if($ENV{'MOD_PERL'}) { require Apache; }
my $this = new();
$this->start;
$this->stop;
# →コンストラクタ
sub new {
my $this = new appspage::resbbs::define::;
$this->{'input'} = {};
$this->{'cookie'} = {};
$this->{'config'} = {};
$this->{'recs'} = [];
$this->{'fields'} = {};
$this->{'tmpl'} = {};
#ライブラリ
require($this->{'LIB_DIR'}.'ol_mainlib.cgi');
#ロックオブジェクト
$this->{'lock'} = new
appspage::resbbs::filelock::(
$this->{'LOCK_METHOD'},
$this->{'LOCK_DIR'},
'flock',
$this->{'LOCK_EX'},
$this->{'LOCK_SH'},
$this->{'LOCK_UN'}
);
#データファイルオブジェクト
$this->{'data'} = new
appspage::resbbs::datafile::(
$this->{'DATA_DIR'},
$this->{'TMP_DIR'},
'.cgi',
$this->{'SU_MODE'}
);
#設定ファイル
$this->{'data'}->Compose(
'config',
'config',
'config'
);
#掲示板ファイル
$this->{'data'}->Compose(
'recs',
'recs_r',
'recs',
'<>'
);
#その他
$this->{'header'} = new appspage::resbbs::httpheader::;
$this->{'funcs'} = new appspage::resbbs::funcs::;
$this->{'license'} = new appspage::resbbs::license::;
$this->{'header'}->set_header(
'Content-Type: text/html;accept-charset=Shift_JIS'
);
return bless $this;
}
# →主な処理開始
sub start {
my $this = shift;
#入力値解析
$this->{'req_method'} =
$this->{'funcs'}->parse_input($this->{'input'});
#読込み
if($this->{'input'}->{'m'} eq 'read') {
$this->process_read;
}
#書込み
elsif($this->{'input'}->{'m'} eq 'write') {
$this->{'subtitle'} = '新規投稿';
require($this->{'LIB_DIR'}.'ol_write.cgi');
appspage::resbbs::main::write::process_write($this);
}
#返事を投稿(1)
elsif($this->{'input'}->{'m'} eq 'res') {
$this->{'subtitle'} = '返事を投稿';
$this->process_res;
}
#返事を投稿(2)
elsif($this->{'input'}->{'m'} eq 'res_write') {
$this->{'subtitle'} = '返事を投稿';
require($this->{'LIB_DIR'}.'ol_write.cgi');
appspage::resbbs::main::write::process_res_write($this);
}
#留意事項
elsif($this->{'input'}->{'m'} eq 'readme') {
$this->{'subtitle'} = '留意事項';
$this->process_readme;
}
#使い方
elsif($this->{'input'}->{'m'} eq 'usage') {
$this->{'subtitle'} = '使い方';
$this->process_usage;
}
#編集
elsif($this->{'input'}->{'m'} eq 'edit') {
$this->{'subtitle'} = '削除';
$this->process_edit;
}
#編集(削除)
elsif($this->{'input'}->{'m'} eq 'edit_delete') {
$this->{'subtitle'} = '削除';
require($this->{'LIB_DIR'}.'ol_write.cgi');
appspage::resbbs::main::write::process_edit_delete($this);
}
#管理用(1)
elsif($this->{'input'}->{'m'} eq $this->{'ADMIN_KEY'}) {
require($this->{'LIB_DIR'}.'ol_admin.cgi');
appspage::resbbs::main::admin::process_admin($this);
}
#管理用(2)
elsif($this->{'input'}->{'m'} eq $this->{'ADMIN_KEY'}.'.2') {
require($this->{'LIB_DIR'}.'ol_admin.cgi');
appspage::resbbs::main::admin::process_admin2($this);
}
#その他
elsif($this->{'input'}->{'m'} eq 'chart') {
$this->out_chart;
}
elsif($this->{'input'}->{'m'} eq 'license') {
$this->{'header'}->send_header;
$this->{'license'}->to_verify($this->{'LICENSE'});
}
elsif($this->{'input'}->{'m'} eq '') {
$this->{'input'}->{'m'} = 'read';
$this->process_read;
}
else { $this->error('Q'); }
}
# →読込み
sub process_read {
my $this = shift;
my($x,$y);
my $rep =
sub { return $_[0].' = '.$this->{'fields'}->{$_[0]}; };
my $page =
sub { return $_[0].' = '.$this->{'page'}->{$_[0]}; };
my $cookie =
sub { return $_[0].' = '.$this->{'cookie'}->{$_[0]}; };
if(
$this->{'input'}->{'page'} < 1
||
$this->{'input'}->{'page'} =~ /\D/
)
{ $this->{'input'}->{'page'} = 1; }
#クッキーの解析
$this->{'funcs'}->parse_cookie(
$this->{'cookie'},
$this->{'CK_NAME'}
);
########## 区切 ##########
#セッション
$this->{'data'}->Compose(
'session',
'session_s',
'session',
$this->{'SESS_CHAR'},
$this->{'SALT'}
);
########## 区切 ##########
if(!$this->{'lock'}->lock('SH')) { $this->error('B'); }
#設定値
if(
!$this->{'data'}->{'file'}->{'config'}->Open
||
!$this->{'data'}->{'file'}->{'config'}->Load(
$this->{'config'},
'display',
'recs',
'session',
'tag',
'counter'
)
) { $this->error('F'); }
$this->{'data'}->{'file'}->{'config'}->Close;
#有効なリクエストのみ実行
my $check;
if(
($this->{'input'}->{'page'} * $this->{'config'}->{'page_recs'})
<=
$this->{'config'}->{'max_recs'}
)
{
#開く
if(!$this->{'data'}->{'file'}->{'recs'}->Open) { $this->error('F'); }
#読む
(
$check,
$this->{'page'}->{'prev'},
$this->{'page'}->{'next'},
$this->{'page'}->{'recs_count'}
)
=
$this->{'data'}->{'file'}->{'recs'}->Readlines(
$this->{'input'}->{'page'},
$this->{'config'}->{'page_recs'},
$this->{'config'}->{'recs_count'},
$this->{'recs'}
);
#閉じる
$this->{'data'}->{'file'}->{'recs'}->Close;
}
$this->{'lock'}->unlock;
########## 区切 ##########
#ページ情報
my $value = 1;
if(!@{$this->{'recs'}}) { $value = 0; }
$this->{'page'}->{'begin'} =
$this->{'config'}->{'page_recs'} *
($this->{'input'}->{'page'} - 1) +
$value
;
$value = @{$this->{'recs'}} - 1;
if($value < 0) { $value = 0; }
$this->{'page'}->{'end'} = $this->{'page'}->{'begin'} + $value;
#無効なページ
if(!$check && $this->{'input'}->{'page'} > 1) {
$this->{'page'}->{'begin'}++;
$this->error(
'現在、'.
$this->{'page'}->{'begin'}.
'件目以降の記事は存在しません。'
);
}
#クッキー処理
if($this->{'cookie'}->{'url'} eq '') {
$this->{'cookie'}->{'url'} = 'http://';
}
########## 区切 ##########
#ヘッダ
$this->out_header_block;
#フォーム
$this->{'tmpl'}->{'main'}->PrintBlock(
'form','nos',
"session = ".$this->{'data'}->{'file'}->{'session'}->Createvar,
$cookie->('name'),
$cookie->('mail'),
$cookie->('url'),
$cookie->('passw'),
"switch = ".$this->{'funcs'}->switch_by_val(
$this->{'cookie'}->{'on'}
),
);
#メニュー(1)
$this->{'tmpl'}->{'main'}->PrintBlock(
'menu','nos',
"home = $this->{'config'}->{'home'}"
);
#広告挿入
if($this->{'ADVERT_TOP'} ne '') {
print '