#!/usr/local/bin/perl # ### CGI掲示板(超簡易版) SD-Note-Spade Ver.1.0 ### ### (C) 2000 Sentora Dori ### http://www.lowpower.iis.u-tokyo.ac.jp/~hat # ########## 変数設定 ########## #----- 手動設定部 ----- # 掲示板データファイルをおくディレクトリのパス $basedir = "./"; # 掲示板データファイル名 (要変更) $bbsfile = 'SDnote00.txt'; # 掲示板のタイトル (要変更) $title = '道里千虎の掲示板'; # コメント $comment = ''; # 背景の色 $bgcolor = '#FFFFFF'; # 背景に埋め込む画像 $bgimage = ''; # 1ページに表示される記事の数 $pagesize = 3; # ファイルに記録しておく記事の数 #(記事がこれ以上になると古いものから削除される。0に設定すると削除なし。) $maxarticle = 100; # post: postメソッド get: getメソッド $method = 'post'; # 漢字コード(sjis or jis or euc) $kanjicode = 'sjis'; #----- 自動設定部 ----- $needname = 1; $needsubject = 1; $maxmessage = 3000; $notecolor = '#FF0000'; $tableborder = 0; $tablecolor = ''; $showmail = 1; $showurl = 1; $uselock =1; $jcodelib ='./jcode.pl'; $thisurl = 'SDnoteS10.cgi'; $signature = 'bbs'; ########## 変数設定(ここまで) ########## $bbsfile = $basedir.$bbsfile; #----- 漢字コード設定 ----- require "$jcodelib"; if ($kanjicode eq 'sjis') { $contenttype = ""; # $contenttype = ""; } elsif ($kanjicode eq 'euc') { $contenttype = ""; # $contenttype = ""; } elsif ($kanjicode eq 'jis') { $contenttype = ""; } ##### format ##### #----- ユーザからの情報取得 ----- &init_form($kanjicode); $bakaddr = $ENV{'REMOTE_ADDR'}; $bakhost = $ENV{'REMOTE_HOST'}; ($bakaddr eq $bakhost) && ($hostname = gethostbyaddr(pack("C4", split(/\./, $bakaddr)), 2)); $hostaddress = $bakaddr; #----- 変数入力 ----- $bbs_name = $form{'bbs_name'}; $bbs_subject = $form{'bbs_subject'}; $bbs_mail = $form{'bbs_mail'}; $bbs_url = $form{'bbs_url'}; $bbs_message = $form{'bbs_message'}; $bbs_command = $form{'bbs_command'}; $bbs_id = $form{'bbs_id'}; $bbs_hostname = $form{'bbs_hostname'}; $bbs_hostaddress = $form{'bbs_hostaddress'}; $bbs_pagenumber = $form{'bbs_pagenumber'}; #----- タグ禁止 ----- $bbs_name = &norm_input($bbs_name); $bbs_subject = &norm_input($bbs_subject); $bbs_mail = &norm_input($bbs_mail); $bbs_url = &norm_input($bbs_url); $bbs_message = &norm_input($bbs_message); $bbs_id = &norm_input($bbs_id); ##### branch(入力されたコマンドによる分岐) ##### if ($bbs_command eq 'read') { &do_read; } elsif ($bbs_command eq 'write') { &do_write; } else { &do_read; } exit(0); ###### do(コマンド実行) ##### #----- 記事を読む(単に表示する) ----- sub do_read { &show_article; } #----- 記事を書く(ファイルに書いて表示する) ----- sub do_write { ### a 入力情報の検証 ###; $error= ''; if ($needname == 1 && $bbs_name eq '') { $error .= '名前が入力されていません。
'; } if ($needsubject == 1 && $bbs_subject eq '') { $error .= '題名が入力されていません。
'; } if ($bbs_message eq '') { $error .= 'メッセージが入力されていません。
'; } if ($error) { &print_error("$error"); } if ($maxlength >0 && length($bbs_message) > $maxmessage) { &print_error('メッセージが長すぎます。'); } ### b ファイルへ書き込み ### &open_file(BBS, "+<$bbsfile", "No bbs file"); &lock_file(BBS); @bbs = ; # 掲示板ファイルかどうかチェック ($sign, $masterpass) = splice(@bbs, 0, 2); chop($sign); chop($masterpass); if ($sign ne $signature) { &unlock_file(BBS); &close_file(BBS); &print_error("Not BBS file"); } # リロードかどうかチェックし連続書き込みを防止する ($print_id, $print_name, $print_mail, $print_url, $print_date, $print_pass, $print_subject, $print_message, $print_hostname, $print_hostaddress) = split(/,/, $bbs[0]); if ($print_name eq $bbs_name && $print_subject eq $bbs_subject && $print_message eq $bbs_message) { &unlock_file(BBS); &close_file(BBS); &show_article; exit(0); } # 書き込み準備 seek(BBS, 0, 0); print BBS "$sign\n"; print BBS "$masterpass\n"; $datestr = &get_date_string; if ($bbs_url eq 'http://') { $bbs_url = ''; } # 書き込み位置検出 $id = 1; for ($i = 0; $i < @bbs; $i++) { ($bakid) = split(/,/, $bbs[$i]); if ($bakid >= $id) { $id = $bakid + 1; } } $writeline = "$id,$bbs_name,$bbs_mail,$bbs_url,$datestr,$encpass,$bbs_subject,$bbs_message,$hostname,$hostaddress\n"; unshift(@bbs, $writeline); if ($maxarticle != 0) { splice (@bbs, $maxarticle); } # 書き込み print BBS @bbs; truncate(BBS, tell(BBS)); &unlock_file(BBS); &close_file(BBS); ### c 表示 ### &show_article; } ##### show(HTML表示) ##### #----- 書き込み用フォームと記事を表示する ----- sub show_article { @file_info = stat($bbsfile); if ($file_info[7] == 0) { &open_file(BBS, "+<$bbsfile", "No BBS file"); seek(BBS, 0, 0); print BBS "$signature\n"; print BBS "\n"; &close_file(BBS); } # open &open_file(BBS, "$bbsfile", "No BBS file"); @bbs = ; &close_file(BBS); # check signiture ($sign, $masterpass) = splice(@bbs, 0, 2); chop($sign); chop($masterpass); $number_article = $#bbs + 1; if ($sign ne $signature) { &print_error("No BBS file"); } print "Content-type: text/html\n"; print "\n"; # ヘッダ表示 print <<"END_SHOW_ARTICLE_HEAD"; $contenttype $title
$title
$comment
END_SHOW_ARTICLE_HEAD # 書き込み用フォーム表示 if ($needname) { $print_needname ='(必須)'; } else { $print_needname = ''; } if ($needsubject) { $print_needsubject ='(必須)'; } else { $print_needsubject = ''; } if ($maxarticle != 0) { $print_note = "保存されるメッセージは$maxarticle個で、古い順に消えていきます。
"; } $maxmessage_zenkaku = int($maxmessage / 2); print <<"END_SHOW_ARTICLE_INPUTFORM";
名前 $print_needname
題名 $print_needsubject
E-mail
URL
半角カナ・タグは使えません。最大の文字の長さは全角で$maxmessage_zenkaku文字です。
$print_note

END_SHOW_ARTICLE_INPUTFORM # 記事表示 print "\n"; $article_start = $bbs_pagenumber * $pagesize; $article_end = $article_start + $pagesize; if ($article_end < $number_article) { $bbs_pagenumber++; $shownextpagebutton = 1; } if ($article_end > $number_article) { $article_end = $number_article; } for ($i = $article_start; $i<$article_end; $i++) { ($print_id, $print_name, $print_mail, $print_url, $print_date, $print_pass, $print_subject, $print_message, $print_hostname, $print_hostaddress) = split(/,/, $bbs[$i]); if ($showmail && $print_mail) { $print_nametag = "$print_name"; } else { $print_nametag = "$print_name"; } if ($showurl) { $print_urltag = "$print_url"; } else { $print_urltag = ""; } print <<"END_SHOW_ARTICLE_ARTICLE"; No.$print_id   $print_nametag   題名: $print_subject   $print_urltag   $print_date

$print_message

END_SHOW_ARTICLE_ARTICLE } # フッター表示 if ($shownextpagebutton) { print <<"END_SHOW_NEXTPAGEBUTTON";
END_SHOW_NEXTPAGEBUTTON } print <<"END_SHOW_ARTICLE_FOOT"; END_SHOW_ARTICLE_FOOT } ##### サブ処理 ##### #----- 時刻文字列の取得 ----- sub get_date_string { local(@week) = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); local($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime(time); $year += 1900; $mon++; if ($hour < 10) { $hour = "0$hour"; } if ($min < 10) { $min = "0$min"; } if ($sec < 10) { $sec = "0$sec"; } $weekstr = $week[$weekday] ; return "$year-$mon-$day ($weekstr) $hour:$min"; } ##### 入出力処理 ###### #----- ブラウザへの入力データの取得 ----- sub init_form { local($query, @dataarray, $data, $property, $value, $charcode, $method); $charcode = $_[0]; $method = $ENV{'REQUEST_METHOD'}; $method =~ tr/A-Z/a-z/; if ($method eq 'post') { read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } else { $query = $ENV{'QUERY_STRING'}; } @dataarray = split(/&/, $query); foreach $data (@dataarray) { ($property, $value) = split(/=/, $data); $value =~ tr/+/ /; $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; &jcode'convert(*value, $charcode); $form{$property} = $value; } } #----- 入力データからのタグ、メタ文字の消去 ----- sub norm_input { local($string) = @_; $string =~ s/&/&/g; $string =~ s/"/"/g; $string =~ s//>/g; $string =~ s/,/,/g; $string =~ s/\r\n/\n/g; $string =~ s/\r/\n/g; $string =~ s/\n\n/

/g; $string =~ s/\n/
/g; return $string; } ##### ファイル処理 ##### #----- ファイルオープン ----- sub open_file { local(*FILE, $name, $msg) = @_; if (!open(FILE, $name)) { &print_error("$msg"); } seek(FILE, 0, 0); } #----- ファイルクローズ ----- sub close_file { local(*FILE) = @_; close(FILE); } #----- ファイルロック ----- sub lock_file { local(*FILE) = @_; if ($uselock) { eval("flock(FILE, 2)"); if ($@) { &print_error("Cannot use flock"); } } } #----- ファイルアンロック ----- sub unlock_file { local(*FILE) = @_; if ($uselock) { eval("flock(FILE, 8)"); } } ##### エラー処理 ##### #----- エラー文を出力し終了 ----- sub print_error { local($msg) = @_; print "Content-type: text/html\n\n"; print <<"END_PRINT_ERROR"; $contenttype $msg

$msg



戻る END_PRINT_ERROR exit(0); }