#!/usr/local/bin/perl5
## ----------------------------------------------------------------------------
## G-LIGHT v4.4
## by KENT (99/06/12)
## E-MAIL kent@lemon.ne.jp
## HomePage http://www.lemon.ne.jp/~kent/
$| = 1;
$ver = 'G-LIGHT v4.4'; # バージョン情報(修正不要)
## -----[注意事項ほか]----------------------------------------------------------
## ・このスクリプトはフリーソフトです。このスクリプトを使用したいかなる損害に
## 対して作者は一切の責任を負いません。
## ・設置に関する質問はサポート掲示板にお願いいたします。メールによる質問には
## お答えできません。
## -----------------------------------------------------------------------------
require './jcode.pl'; # jcode.plが同一ディレクトリにある場合
## 基本設定
$pass = '1022'; # 管理用パスワード
$subject = 1; # 「題名」欄の有無 (0=no 1=yes)
$counter = 1; # ミニカウンタの有無 (0=no 1=テキスト 2=GIF画像)
$mini_fig = 7; # ミニカウンタの桁数
$cnt_color = "#DD0000"; # テキストのとき:ミニカウンタの色
$gif_url = "."; # GIFのとき :画像までのディレクトリ
$mini_w = 8; # 〃 :画像の横サイズ
$mini_h = 12; # 〃 :画像の縦サイズ
$cntfile = './count.dat'; # カウンタファイル
$tagkey = 0; # タグの許可(0=no 1=yes)
$script = './glight2.cgi'; # スクリプトファイル名
$logfile = './glight.log'; # ログファイル名
$method = 'POST'; # methodの形式(POST or GET)
$pagelog = 20; # 1ページ当たりの記事表示数
$lockkey = 0; # ファイルロック処理 (0=no 1=symlink 2=open)
$lockfile = 'glight.lock'; # ロックファイル名
$lock_dir = "."; # ロックファイルのディレクトリ
$wrap = 'soft'; # 投稿ファーム内の改行形式 (soft=改行なし hard=強制)
$autolink = 1; # URLの自動リンク (0=no 1=yes)
$mailing = 0; # 自動メール通知の有無 (0=no 1=yes)
$sendmail = '/usr/lib/sendmail'; # sendmailパス(メール通知する時)
$mail_me = 0; # 自分の記事もメールする (0=no 1=yes)
## ---- <過去ログ> -------------------- #
$pastkey = 0; # 過去ログ機能 (0=no 1=yes)
$pastno = "./pastno.dat"; # 過去ログ用NOファイル
$log_line = 150; # 過去ログ1ファイル当たりの行数
$past_dir = "."; # 過去ログディレクトリ(フルパスだと / から)
$past_url = "."; # 過去ログディレクトリのURL(絶対パスだと http:// から)
## --- <画像関連> --------------------- #
$img_url = "."; # キャラクタGIF画像のディレクトリを指定
# キャラクタを指定(上下の配列はペアで)
@GFILE = ('boy1.gif','boy2.gif','fanta_icon/boy2.gif','fanta_icon/seinen.gif','girl1.gif','girl2.gif','fanta_icon/girl2.gif','fanta_icon/ol1.gif','fanta_icon/ol2.gif','fanta_icon/ol3.gif','heisi1.gif','heisi2.gif','majo.gif','king.gif','ani1.gif','ani2.gif','admin1.gif','admin2.gif','admin3.gif','admin4.gif','fanta_icon/cook.gif','fanta_icon/china.gif');
@CHARA = ('少年1','少年2','少年3','少年4','少女1','少女2','少女3','女性1','女性2','女性3','兵士1','兵士2','魔女','王様','動物1','動物2','かめ','うさぎ','くま','ねこ','コック','中国人');
# 地域名
@areas = ('名古屋大学','金城大学','椙山大学','北海道','東北','関東','甲信越','東海','北陸','近畿','中国','四国','九州','外国','地球外');
# 管理者キャラクタを指定(上下の配列はペアで)
@ADMIN_GFILE = ('admin1.gif','admin2.gif','admin3.gif','admin4.gif','king.gif');
@ADMIN_CHARA = ('かめ','うさぎ','くま','ねこ','王様');
## 設定ここまで
## ロックファイルを定義
$lockfile = "$lock_dir\/$lockfile";
## --- G-LIGHT のメイン処理
&form_decode;
if ($mode eq "usr_del") { &usr_del; }
elsif ($mode eq "regist") { ®ist; }
elsif ($mode eq "find") { &find; }
elsif ($mode eq 'past') { &past; }
elsif ($mode eq 'edit') { &edit; }
elsif ($mode eq 'edit_msg') { &edit_msg; }
elsif ($mode eq 'delete') { &delete; }
elsif ($mode eq 'del_msg') { &del_msg; }
elsif ($mode eq 'env') { &env; }
elsif ($mode eq 'env_init') { &env_init; }
elsif ($mode eq "enter") { &enter; }
elsif ($mode eq "image") { ℑ }
&html_log;
## --- HTMLのヘッダー
sub header{
print "Content-type: text/html\n\n";
print "\n
\n";
print "\n";
print "$title\n";
if (!$bgc) {
print "\n";
} elsif ($bgr) {
print "\n";
} else {
print "\n";
}
print "
\n";
}
## --- 記事表示部
sub html_log {
&get_cookie;
$agent = $ENV{'HTTP_USER_AGENT'};
# MSIE3 の場合フォームの長さを調整
if ($agent =~ /MSIE 3/i) {
$nam_wid = 30;
$com_wid = 65;
$url_wid = 48;
$sub_wid = 40;
# MSIE4 の場合フォームの長さを調整
} elsif ($agent =~ /MSIE 4/i) {
$nam_wid = 30;
$com_wid = 65;
$url_wid = 75;
$sub_wid = 40;
} else {
$nam_wid = 20;
$com_wid = 55;
$url_wid = 45;
$sub_wid = 30;
}
# ログを読みこみ
&open_log2;
# 環境設定部を認識
($head,$title,$t_color,$t_size,$t_face,$bgr,$bgc,$text,
$link,$vlink,$alink,$home,$max,$sbj_color,$mailto,
$manager,$man_color) = split(/<>/, $init);
# ログチェック
unless ($init =~ /^GLIGHT/) { &log_err; }
&header;
# カウンタ処理
if ($counter) { &counter; }
print "\n";
print "\n";
print "$title
\n";
print "[トップにもどる]\n";
print "[ワード検索]\n";
if ($pastkey) {
print "[過去ログ]\n";
}
print "[管理用]\n";
print "
\n";
print "
1. お名前とメッセージ欄は必須です。
2. 記事は最大$max件まででそれを超えると古い記事から削除されます。
3. 削除キーは英数字で8文字以内で指定して下さい。
HTML
if ($FORM{'page'} eq '') { $page = 0; }
else { $page = $FORM{'page'}; }
# 記事数を取得
$end_data = @lines - 1;
$page_end = $page + ($pagelog - 1);
if ($page_end >= $end_data) { $page_end = $end_data; }
foreach ($page .. $page_end) {
($no,$date,$name,$email,$local,$icon,$ad_ico,
$com,$res,$url,$host,$pw,$sub) = split(/<>/,$lines[$_]);
# 自動URLリンク
if ($autolink) { &auto_link($com); &auto_link($res); }
# Eメールをリンク
if ($email) { $name="$name"; }
print "[$no] \n";
if ($subject == 1) {
if ($sub eq "") { $sub = "no title"; }
print "$sub | | \n";
print "投稿者:$name\n";
print "[$local] 投稿日:$date | \n";
} else {
print "$name\n";
print "[$local] $date | \n";
}
if ($url) {
print " | ";
print " | \n";
}
print "
\n";
print " | \n";
print " | $com |
\n";
if ($res) {
print " | \n";
print " | | \n";
print "$res \n";
print "[From $manager]\n";
print " |
\n";
}
print "
\n";
}
# 改頁処理
print "\n";
## 著作権を表示(削除禁止)
print "\n";
print "- G-LIGHT -\n";
print "\n";
print "\n";
exit;
}
## --- ログ書き込み処理
sub regist {
# フォームチェック
if ($FORM{'name'} eq "") { &error("名前が入力されていません。",'NOLOCK'); }
if ($FORM{'comment'} eq "") { &error("コメントが入力されていません。",'NOLOCK'); }
# クッキーをブラウザに格納
&set_cookie;
# ロック開始
if ($lockkey == 1) { &lock1; }
elsif ($lockkey == 2) { &lock2; }
# ログを開く
&open_log1;
unless ($init =~ /^GLIGHT/) { &log_err; }
# 設定を認識
($head,$title,$t_color,$t_size,$t_face,$bgr,$bgc,$text,$link,
$vlink,$alink,$home,$max,$sbj_color,$mailto,
$manager,$man_color) = split(/<>/, $init);
# 二重投稿の禁止
($knum,$kda,$kname,$kem,$klo,$ki,$kad,$kcom) = split(/<>/, $lines[0]);
if ($name eq $kname && $comment eq $kcom) { &error("二重投稿は禁止です"); }
## 過去ログを取得する場合
if ($pastkey && $#lines >= $max-1) { &pastlog; }
# 記事Noカウント及び最大記事数超を切り捨て
$number = $knum + 1;
if ($#lines >= $max-1) { splice(@lines,$max-1); }
# 削除キーを暗号化
if ($pwd) { &pass_ango("$pwd"); }
# ホスト名及び時間を取得
&get_host;
&get_time;
# ログをフォーマット
unshift(@lines,"$number<>$date<>$name<>$email<>$area<>$icon<><>$comment<><>$url<>$host<>$ango<>$subj<>\n");
unshift(@lines,$init);
# ログを更新
open(OUT,">$logfile") || &error("Can't write $logfile");
print OUT @lines;
close(OUT);
# ロック解除
if (-e $lockfile) { unlink($lockfile); }
# メール処理
if ($mailto && $mail_me) { &mail_to; }
elsif ($mailto && $mail_me == 0 && $email ne "$mailto") { &mail_to; }
# 記事表示部に戻る
&html_log;
}
## --- フォームからのデータ処理
sub form_decode {
if ($ENV{'REQUEST_METHOD'} eq "POST") {
if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます。",'NOLOCK'); }
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else { $buffer = $ENV{'QUERY_STRING'}; }
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# 文字コード変換
&jcode'convert(*value,'sjis');
# タグ処理
if ($tagkey == 0) {
$value =~ s/\"/"/g;
$value =~ s/</g;
$value =~ s/>/>/g;
} else {
$value =~ s///g;
$value =~ s/<>/<>/g;
}
# 削除情報
if ($name eq 'del') { push(@dels,$value); }
$FORM{$name} = $value;
}
$name = $FORM{'name'};
$comment = $FORM{'comment'};
$comment =~ s/\r\n/
/g;
$comment =~ s/\r|\n/
/g;
$FORM{'res_msg'} =~ s/\r\n/
/g;
$FORM{'res_msg'} =~ s/\r|\n/
/g;
$email = $FORM{'email'};
$url = $FORM{'url'};
$url =~ s/^http\:\/\///;
$mode = $FORM{'mode'};
$area = $FORM{'area'};
$icon = $FORM{'icon'};
$pwd = $FORM{'pwd'};
$com = $FORM{'com'};
$com =~ s/\r\n/
/g;
$com =~ s/\r|\n/
/g;
$res = $FORM{'res'};
$res =~ s/\r\n/
/g;
$res =~ s/\r|\n/
/g;
$subj = $FORM{'subj'};
}
## --- 日時の取得
sub get_time {
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
$year = 1900 + $year;
$mon++;
if ($mon < 10) { $mon = "0$mon"; }
if ($mday < 10) { $mday = "0$mday"; }
if ($hour < 10) { $hour = "0$hour"; }
if ($min < 10) { $min = "0$min"; }
$week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat') [$wday];
# 日時のフォーマット
$date = "$year/$mon/$mday($week) $hour\:$min";
}
## --- エラー表示処理
sub error {
if ($_[1] ne '0') { &header; }
if (-e $lockfile && $_[1] eq "") { unlink($lockfile); }
print "
ERROR !
\n";
print "$_[0]\n";
print "
\n";
print "\n";
exit;
}
## --- 記事削除処理
sub usr_del {
if ($FORM{'usr_no'} eq "" || $FORM{'usr_key'} eq "") {
&error("削除No又は削除キーが入力されていません。",'NOLOCK');
}
# ロック開始
if ($lockkey == 1) { &lock1; }
elsif ($lockkey == 2) { &lock2; }
# ログを読み込む
&open_log1;
@new = ();
$no_del = 0;
## 削除キーによる記事削除 ##
foreach $line (@lines) {
($number,$date,$name,$email,$local,$icon,$ad_icon,$com,
$res,$url,$host,$ango) = split(/<>/,$line);
$flag = 0;
if ($FORM{'usr_no'} eq "$number") {
if ($ango eq "") { $no_del = 1; last; }
# パスワード照合
&pass_shogo($FORM{'usr_key'});
if ($check eq "yes") { $flag = 1; }
else { $no_del = 2; last; }
}
if ($flag == 0) { push(@new,$line); }
}
if ($no_del == 1) { &error("削除キーが設定されていません。"); }
elsif ($no_del == 2) { &error("パスワードが違います。"); }
unshift(@new,$init);
# ログを更新
open(DB,">$logfile") || &error("Can't write $logfile");
print DB @new;
close(DB);
# ロック解除
if (-e $lockfile) { unlink($lockfile); }
# 初期画面にもどる
&html_log;
}
## --- ワード検索サブルーチン
sub find {
open(IN,"$logfile") || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(IN);
($head,$title,$t_color,$t_size,$t_face,$bgr,$bgc,
$text,$link,$vlink,$alink,$home,$max,$sub_color,
$mailto,$manager,$man_color) = split(/<>/, $lines[0]);
&header;
print <<"EOM";
▲ BBS
- 検索したいキーワードを入力し、検索条件を選択し「検索する」を押してください。
- 複数のキーワードを入力するときは、半角スペースで区切って下さい。
EOM
if ($pastkey) {
print "
- 過去ログは新着順に5ファイル毎に区切っています。\n";
}
print <<"EOM";
|
\n";
# ワード検索の実行と結果表示
if ($FORM{'word'} ne "") {
# 入力内容を整理
$cond = $FORM{'cond'};
$word = $FORM{'word'};
$word =~ s/ / /g;
$word =~ s/\t/ /g;
@pairs = split(/ /,$word);
# 現行ログのとき
if ($FORM{'log'} == 0) {
# ファイルを読み込み
open(DB,"$logfile") || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(DB);
shift(@lines);
# 過去ログのとき
} else {
# 検索領域を定義
$start = 5 * $FORM{'log'} - 4;
@lines = ();
foreach ($start .. $start+5) {
unless(-e "$past_dir\/$_\.html") { last; }
open(DB,"$past_dir\/$_\.html");
@temp = ;
close(DB);
push(@lines,@temp);
}
}
# 検索処理
foreach $line (@lines) {
$flag = 0;
foreach $pair (@pairs){
if (index($line,$pair) >= 0) {
$flag = 1;
if ($cond eq 'or') { last; }
} else {
if ($cond eq 'and') { $flag = 0; last; }
}
}
if ($flag == 1) { push(@new,$line); }
}
# 検索終了
$count = @new;
print "
検索結果:$count件\n";
print "\n";
if ($FORM{'log'} == 0) {
foreach $line (@new) {
($num,$date,$name,$email,$local,$icon,$ad_ico,$com,$res,$url,
$host,$pw,$sub) = split(/<>/,$line);
if ($subject && !$sub) { $sub = "no title"; }
if ($email) { $name = "$name"; }
if ($url) { $url = "http://$url"; }
# 結果を表示
print "- [$num] $sub\n";
print "投稿者:$name 投稿日:$date\n";
print "
$com$url
\n";
}
} else {
foreach $line (@new) {
($p1,$p2) = split(/<\!--T-->/, $line);
print " - $p1 \- $p2\n";
}
}
}
print "
\n";
print "