#!/usr/bin/perl
#| JawaNote version 1.41.02
#| This script is free.
#|
#| Author Shigeto Nakazawa.(1998/01/17)
#| HomePageUrl http://www7.big.or.jp/~jawa/
# //////////////////////////////////////////////////////////
# オプションの設定を変更することができます。
# 変更する場合は、readme.htm をご覧になってから行ってください。
# 設定変更には充分注意してください。
# //////////////////////////////////////////////////////////
# ----------------------------------------------------------
# じゃわのーとの管理者(あなた)の情報です。
# ----------------------------------------------------------
$admin_name = '管理人'; # あなたの名前(ハンドルネーム)を書きます。
$admin_email = 'info@ouzan.net'; # あなたのメールアドレスを書きます。
$master = 'miko'; # 管理用のパスワード
# ----------------------------------------------------------
# じゃわのーとのカスタマイズ項目です。
# ----------------------------------------------------------
$reg_max = 300; # 最大保持数(最大9998まで)
$max = 30; # 1ページに表示する数です。
$max_msg = 1200; # 投稿を受理する最大文字数(半角 n 文字)
$note_title = "イベント告知板"; # タイトル
$body = '
';
# タグ
$backurl = "../../index.html"; # 帰りのページの URL
$form_position = 0; # フォームの位置(上:0 下:1 なし:2)
$note_color = 'black'; # 掲示板のタイトル色
$number_color = '#FF0000'; # 数字関係の色
$title_color = '#0000FF'; # 投稿のタイトルの色
$tback_color = '#F3F3F3'; # 投稿のタイトルの背景色
$mback_color = '#FFFFFF'; # 投稿のメッセージの背景色
# 書き込む時の選択色(約7色まで)
$colors[0] = '#000000'; # 黒(ここには標準の色を設定)
$colors[1] = '#972100'; # 茶
$colors[2] = '#437D22'; # 緑
$colors[3] = '#00329F'; # 青
$colors[4] = '#7C317A'; # 紫
$colors[5] = '#F06820'; # オレンジ
$gethostaddr = 1; # リモートホストが正しく表示されない場合は、ここを 1 にす
# るとうまく表示されることがあります。
#(ただし、サーバーエラーの原因になることもあります。)
$check_url = ""; # ここに JawaNote の正確な URL (http://〜) を書いておくと
# 他サイトから不正に投稿されたものを拒否できます。
# (イタズラされて、初めて利用すること!)
@check_ipad = (); # ここに 登録されたくない方の IPアドレスを書いておくと、
# その IPアドレスからの全ての投稿を拒否します。
# (イタズラされて、初めて利用すること!)
$check_proxy = 0; # ここの値を 1 にすると、プロクシ経由で来る匿名な訪問者を
# 排除ですきますが、通常の方を排除する可能性もあります。
# (イタズラされて、初めて利用すること!)
# ファイル関連の設定
$cookie_name = 'event'; # クッキー用ID
$cginame = 'event.cgi'; # この CGI のファイルの名前
$jcode = './jcode.pl'; # jcode.pl のある場所
$logfile = './event.log'; # 記録用ファイル
$lock1 = './event1.lock'; # 鍵ファイル(1)
$lock2 = './event2.lock'; # 鍵ファイル(2)
$lock_flag = 1; # 鍵ファイルの 1:使用 0:不使用
# //////////////////////////////////////////////////////////
# オプションの設定はここまでです。
# 以下は CGI のプログラムです。
# 書き換えは個人の責任で行って下さい。
# //////////////////////////////////////////////////////////
&check_code;
&read_form;
if ($FORM{'func'} eq 'form') {
&html_header;
&html_title;
&put_form;
&html_footer;
exit;
}
@logs = &read_file($logfile);
if ($FORM{'pass'} eq $master) {
if ($FORM{'func'} eq 'unlock') { &editor_unlock; }
if ($FORM{'func'} eq 'html') { &download; }
if ($FORM{'func'} eq 'download') { &editor_download; }
if ($FORM{'func'} eq 'del') { &editor_del; }
&editor_main;
}
if ($FORM{'func'} eq 'reg') { ®ist; }
if ($FORM{'func'} eq 'dl' ) { &download; }
if ($FORM{'func'} eq 'password') { &editor_password;}
&html_header;
&html_title;
if ($form_position == 0) { &put_form;&put_list; }
elsif ($form_position == 1) {
&put_list;
print "
\n";
&put_form;
} elsif ($form_position == 2) { &put_list; }
&put_function;
&html_footer;
exit;
# [ HTMLヘッダー部 ]
#
sub html_header {
print<<"_EOF_";
Content-type: text/html
$note_title
$body
_EOF_
}
# [ HTMLタイトル部 ]
#
sub html_title {
print<<"_EOF_";
$note_title
_EOF_
}
# [ 著作権の表示(書き換えずに、必ず表示すること) ]
#
sub html_footer {
print<<"_EOF_";
_EOF_
}
# [ Function表示部 ]
#
sub put_function {
print<<"_EOF_";
|
|
全ての投稿を HTML 化してダウンロードできます。
ダウンロード後、ファイル名を event.htm に変更して利用下さい。
|
_EOF_
}
# [ 登録リスト表示部 ]
#
sub put_list {
print "
\n";
print "\n";
local($page) = $FORM{'page'};
local($next_page,$back_page) = ($page-$max,$page+$max);
if ($back_page > @logs-1) {
$back_page = @logs;
print "[BACK]";
} else {
print "[BACK]";
}
if ($next_page < 0) {
print "[NEXT]";
} else {
print "[NEXT]";
}
print "\n";
print "
\n";
for ($i=$page;$i<$back_page;$i++) {
&put_format($logs[$i]);
}
}
# [ 登録リスト表示フォーマット ]
#
sub put_format {
local($no,$title,$name,$url,$email,$date,$pwd,$rhost,$ipad,$color,$comment) = split(/<>/,$_[0]);
&jcode'convert(*comment,'euc');
$comment =~ s/(http:\/\/[\w\.\~\-\/\?\&\+\=\:\@\%]+)/$1<\/A>/ig;
$comment =~ s/(ftp:\/\/[\w\.\~\-\/]+)/$1<\/A>/ig;
$comment =~ s/([\w\.\-]+)\@([\w\.\-]+)/$1\@$2<\/A>/ig;
&jcode'convert(*comment,$mojicode);
if (($color<0) || ($color>@colors)) { $color = 0; }
if ($FORM{'pass'} eq $master) {
print "
\n";
}
print<<"_EOF_";
|
$comment
_EOF_
if ($url) { print " Home\n"; }
if ($email) { print " Mail\n"; }
print<<"_EOF_";
$name $date
|
_EOF_
}
# [ 投稿フォーム表示部 ]
#
sub put_form {
&get_cookie;
if ($FORM{'name'}) { $COOKIE{'name'} = $FORM{'name'}; }
if ($FORM{'url'}) { $COOKIE{'url'} = $FORM{'url'}; }
if ($FORM{'email'}) { $COOKIE{'email'} = $FORM{'email'}; }
if ($FORM{'color'}) { $COOKIE{'color'} = $FORM{'color'}; }
if (($COOKIE{'color'} < 0) || ($COOKIE{'color'} > @colors)) { $COOKIE{'color'} = 0; }
print<<"_EOF_";
_EOF_
}
# [ 投稿登録処理 ]
#
sub regist {
$no = $FORM{'no'};
$title = $FORM{'title'};
$title =~ s/\r\n//g;
$title =~ s/\r|\n//g;
$name = $FORM{'name'};
$name =~ s/\r\n//g;
$name =~ s/\r|\n//g;
$url = $FORM{'url'};
$url =~ s/\r\n//g;
$url =~ s/\r|\n//g;
$email = $FORM{'email'};
$email =~ s/\r\n//g;
$email =~ s/\r|\n//g;
$color = $FORM{'color'};
$color =~ s/\r\n//g;
$color =~ s/\r|\n//g;
$comment = $FORM{'comment'};
$comment =~ s/\r\n/
/g;
$comment =~ s/\r|\n/
/g;
$ref_url = $ENV{'HTTP_REFERER'};
$ref_url =~ s/\?(.|\n)*//ig;
$ref_url =~ s/\%7E/\~/ig;
if($check_url && ($ref_url !~ $check_url)){
&error(1,"不当なアクセスです。
$ref_url
\n");
}
$ipad = $ENV{'REMOTE_ADDR'};
foreach (@check_ipad) {
if ($ipad =~ /^$_/) { &error(1,"$ipad からの投稿は拒否されてます。\n"); }
}
if ($check_proxy) {
local($envkey,$envvalue) = ();
while(($envkey,$envvalue) = each(%ENV)){
if($envkey =~ /proxy/i || $envvalue =~ /proxy/i){
&error(1,"プロクシ経由でのアクセスは禁止されてます。\n");
}
}
}
if (length($title) > 80) {
&error(1,"タイトルの記入漏れ、又は文字数制限を過えています。");
} elsif (!$title) { $title = "無題"; }
if ((!$name) || (length($name) > 42)) {
&error(1,"名前の記入漏れ、又は文字数制限を過えています。");
}
$url =~ s/http\:\/\///;
if (length($url) > 150) {
&error(1,"URLの文字数制限を越えてます。");
}
if ((($email !~ /(.*)\@(.*)\.(.*)/) && ($email)) || (length($email) > 120)) {
&error(1,"メイルアドレスの間違い、又は文字数制限を過えています。");
}
if ((!$comment) || (length($comment) > $max_msg)) {
&error(1,"メッセージの記入漏れ、又は文字数制限を越えています。");
}
for($i=0;$i<@logs;$i++) {
local($no,$ktitle,$kname,$kurl,$kemail,$date,$pwd,$rhost,$ipad,$color,$kcomment) = split(/<>/,$logs[$i]);
$kcomment=~ s/\n$//;
if (($title eq $ktitle) && ($kname eq $name) && ($kurl eq $url) && ($email eq $kemail) && ($comment eq $kcomment)) {
&error(1,'二重投稿は禁止です(二度投稿しないで下さい。)')
}
push(@new,$logs[$i]);
if ($i>$reg_max-3) { last; }
}
($no) = split(/<>/,$logs[0]);
$no = ++$no%9999;
$ENV{'TZ'} = "JST-9"; # TimeZone
local($sec,$min,$hour,$day,$mon,$year) = localtime();
$mon++;
if ($sec < 10) { $sec = "0$sec"; } # 秒の修正
if ($min < 10) { $min = "0$min"; } # 分 〃
if ($hour < 10) { $hour = "0$hour"; } # 時 〃
if ($day < 10) { $day = "0$day"; } # 日 〃
if ($mon < 10) { $mon = "0$mon"; } # 月 〃
if ($year < 99) { $year += 100; }
$year += 1900;
$year = substr($year,length($year)-2,2);
$ipad = $ENV{'REMOTE_ADDR'};
$rhost = $ENV{'REMOTE_HOST'};
if ($gethostaddr) { $rhost = $rhost eq $ipad?gethostbyaddr(pack('C4',split(/\./,$ipad)),2)||'':$rhost; }
unshift(@new,"$no<>$title<>$name<>$url<>$email<>$mon/$day $hour:$min<><>$rhost<>$ipad<>$color<>$comment\n");
@logs = &write_file($logfile,@new);
&put_cookie($name,$email,$url,$color);
$FORM{'url'} = $url;
}
# [ 記事一括ダウンロード処理 ]
#
sub download {
print "Content-type: text/download\n\n";
&html_header;
&html_title;
foreach (@logs) { &put_format($_); }
&html_footer;
exit;
}
# [ エディターメイン(画面の表示等) ]
#
sub editor_main {
&editor_reg;
if ($edit_data) { &editor_edit;}
$kiji = @logs;
$size = (stat($logfile))[7];
if ($lock_flag) {
if (-f $lock1 || -f $lock2) {
$comment = "・ ロックファイルが検出されました(ロック中)
";
} else {
$comment = "・ ロック機構\は正常に動作しています。
";
}
} else {
$comment = "・ ロック機構\を使用していません
";
}
&html_header;
print<<"_EOF_";
\n";
&html_footer;
exit;
}
# [ パスワード入力(エディター) ]
#
sub editor_password {
&html_header;
print<<"_EOF_";
管理用パスワードを入力してください。
(管理用のエディタを使用するためには、管理用パスワードが必要です。)
_EOF_
&html_footer;
exit;
}
# [ ログの編集画面表示 (エディター) ]
#
sub editor_edit {
local($no,$title,$name,$url,$email,$date,$pwd,$rhost,$ipad,$color,$comment) = split(/<>/,$edit_data);
$comment=~ s/\n$//;
&html_header;
print<<"_EOF_";
event Editor
編集したい部分のみ編集して編集ボタンを押して下さい。
_EOF_
$FORM{'name'} = $name;
$FORM{'url'} = $url;
$FORM{'email'} = $email;
$FORM{'color'} = $color;
$no_area = $no;
$title_area = $title;
$text_area = $comment;
$text_area =~ s/
/\n/ig;
&put_form;
&html_footer;
exit;
}
# [ ログの削除・編集(エディター) ]
#
sub editor_reg {
foreach $data (@logs) {
if (!$del[(split(/<>/,$data))[0]]) {
if ($edit_flag) {
if ((split(/<>/,$data))[0] == $edit) {
$edit_data = $data;
}
} elsif ($reg_flag) {
if ((split(/<>/,$data))[0] == $reg) {
local($no,$title,$name,$url,$email,$date,$pwd,$rhost,$ipad,$color,$comment) = split(/<>/,$data);
$comment = $FORM{'comment'};
$comment =~ s/\r\n/
/g;
$comment =~ s/\r|\n/
/g;
$data = "$reg<>$FORM{'title'}<>$FORM{'name'}<>$FORM{'url'}<>$FORM{'email'}<>$date<><>$rhost<>$ipad<>$FORM{'color'}<>$comment\n";
$write_flag = 1;
}
}
push(@new,$data);
} else {
$write_flag = 1;
}
}
if ($write_flag) { @logs = &write_file($logfile,@new); }
}
# [ ロック解除(エディター) ]
#
sub editor_unlock {
&unlock_file($lock1);
&unlock_file($lock2);
}
# [ ログダウンロード(エディター) ]
#
sub editor_download {
print "Content-type: text/download\n\n";
print @logs;
exit 0;
}
# [ ログ初期化(エディター) ]
#
sub editor_del {
@logs = &write_file($logfile,'');
}
# [ フォームからデータ取得 ]
#
sub read_form {
if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; }
local(@pairs) = split(/&/,$buffer);
foreach (@pairs) {
local($name,$value) = split(/=/,$_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
if ($name eq 'del') { $del[$value] = 1; }
elsif ($name eq 'edit') { $edit = $value; $edit_flag = 1; }
elsif ($name eq 'reg') { $reg = $value; $reg_flag = 1; }
else { $FORM{$name} = &change_code($value); }
}
}
# [ 文字コード関連 ]
#
sub check_code {
if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); }
require $jcode;
local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1));
if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }
elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }
else { &error(1,"サポートしてない文字コードです"); }
}
sub change_code {
local($text)=$_[0];
&jcode'convert(*text,$mojicode);
if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }
if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); }
$text =~ s/</g;
$text =~ s/>/>/g;
return $text;
}
# [ 記録ファイルの処理 ]
#
sub read_file {
local($logfile) = $_[0];
if (!open(IN,$logfile)) { &unlock_file; &error(1,"記録ファイルの読み込み不可"); }
local(@files) = ;
close(IN);
return @files;
}
sub write_file {
local($logfile,@lines) = @_;
&lock_file($lock1);&lock_file($lock2);
if ($lock_error) { &error(1,"ロックファイルを検出しました。時間をおいてご利用下さい。"); }
if (!open(OUT,">$logfile")) { &unlock_file; &error(1,"記録ファイルの書き込み不可"); }
print OUT @lines;
close(OUT);
&unlock_file($lock2);&unlock_file($lock1);
return @lines;
}
# [ ロック機構 ]
#
sub lock_file {
local($lockfile) = $_[0];
if (!$lock_flag) { return 1; }
local($retry) = 5;
while (-f $lockfile) {
if ($retry-- <= 0) {
local($mtime) = (stat($lockfile))[9];
if ($mtime < time()-60*15) { &unlock_file($lockfile); }
$lock_error = 1;
return 1;
}
sleep 1;
}
open (LOCK,">$lockfile");
close(LOCK);
return 1;
}
sub unlock_file {
local($lockfile) = $_[0];
unlink($lockfile);
}
# -*- クッキーの処理(まーちゃん改良式) *-*-*-*-*-*-*-
sub put_cookie {
local($name,$email,$url,$color,$pwd) = (@_);
$ENV{'TZ'} = "GMT"; # 国際標準時の取得
local($sec,$min,$hour,$day,$mon,$year,$youbi) =localtime(time + 30*24*60*60);
if ($year < 99) { $year += 100; }
$year += 1900;
if ($year < 10) { $year = "0$year"; }
if ($day < 10) { $day = "0$day"; }
if ($sec < 10) { $sec = "0$sec"; }
if ($min < 10) { $min = "0$min"; }
if ($hour < 10) { $hour = "0$hour"; }
$mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mon];
$youbi = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[$youbi];
$date_gmt = "$youbi, $day\-$mon\-$year $hour:$min:$sec GMT";
$cook="name\:$name\,email\:$email\,url\:$url\,color\:$color\,pwd\:$pwd";
print "Set-Cookie: $cookie_name=$cook; expires=$date_gmt\n";
}
sub get_cookie {
$cookies = $ENV{'HTTP_COOKIE'};
@pairs = split(/;/,$cookies);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ s/ //g;
$DUMMY{$name} = $value;
}
@pairs = split(/,/,$DUMMY{$cookie_name});
foreach $pair (@pairs) {
($name, $value) = split(/:/, $pair);
&jcode'convert(*value,$mojicode);
$COOKIE{$name} = $value;
}
}
# [ エラー処理 ]
#
sub error {
($err,$err_msg) = @_;
if ($err) { print "Content-type: text/html\n\n"; }
print<<"_EOF_";
[ イベント告知板 ]
_EOF_
exit;
}