#! /usr/bin/perl # Perlへのパス↑の行が先頭行になる様にする。 # perlの所在はプロバイダにより異なりますので注意する。 require './jcode.pl'; # 日本語変換ライブラリのパス、既にあればそこまでのパスを指定する。 ################################################################################ # 初期設定 # ↓ データ書き込み後にリロードする時のURL $this_url = 'http://takaq1.plala.jp/contents/homepage/cgi/sample_3/sample_3.cgi'; $data_file = './data_1.dat'; # 投稿したデータを書き込むファイル $data_max = 10; # ファイル内データ件数の最大値 # ################################################################################ # 現在日付と時刻を取得しそれぞれフォーマット編集する # localtime関数で取得 $ENV{'TZ'} = "JST-9"; $now = time; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now); $year += 1900; $mon = sprintf("%02d", $mon + 1); # 月の戻り値は0〜11なので+1して合わせる $mday = sprintf("%02d", $mday); # 日を2桁 $hour = sprintf("%02d", $hour); # 時を2桁 $min = sprintf("%02d", $min); # 分を2桁 $now_time = "$year年$mon月$mday日 $hour時$min分"; # 現在年月日時分 # フォームに書き込まれたデータを「$input_data」に保存します。 # メソッドによって取得方法が異なりますがPOSTでもGETでも取得で # きるようにしています if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $input_data, $ENV{'CONTENT_LENGTH'}); } else { $input_data = $ENV{'QUERY_STRING'}; } # フォームからのデータを分解する # フォームからのデータは「&」で区切られてくるので分解してペアにする @input = split(/&/,$input_data); foreach $data (@input) { ($name, $value) = split(/=/, $data); # 要らない文字の削除・デコードとタグを禁止する $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s//>/g; $value =~ s/\n//g; $value =~ s/\,//g; # jcode.plを呼び出してShift JISに変換 &jcode'convert(*value, 'sjis'); # 分解したデータを連想配列に格納 $FORM{$name} = $value; } # 「$FORM{'action'}」が「true」ならフォームからの呼び出しなので書き込みへ # 初めての呼び出しの場合はHTML作成ルーチンへ if ($FORM{'action'} eq "true") { &data_put; } else{ &html_make; } ################################################################################ # HTMLドキュメント生成ルーチン sub html_make { # サブルーチンの名前定義 if (!open(FILE, "$data_file")) { # データファイルを開く &error_check(bad_file); # エラーの時はメッセージを表示 } @DATA = ; # データを配列に格納 close(FILE); # データファイルを閉じる @DATA = reverse(@DATA); # 読み込みデータを新しい順にソート # HTMLヘッダ部生成 print "Content-type: text/html\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "サンプル BBS_1\n"; # HTML本文 print "\n"; # バックと文字の色 # 入力フォーム print "
\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "\n"; # お名前 print "\n"; print "\n"; print "\n"; print "\n"; # ホームページ print "\n"; print "\n"; print "\n"; print "\n"; # E-Mail print "\n"; print "\n"; print "\n"; print "\n"; # 記事 print "\n"; print "\n"; # 押しちゃうボタン print "\n"; print "\n"; print "\n"; print "
お名前
ホームページ
E-Mail
記事
\n"; print "
\n"; # 記事の表示 data_1.datのデータを行単位で表示します。 print "
\n"; foreach $line_data (@DATA) { chop($line_data); # 行末の改行を削除 # 1行のデータを各項目に分解 ($date, $name, $url, $mail, $kiji) = split(/\, /, $line_data); # $kiji中の「\r」(改行文字)を「
」に変換して入力に合わせる $kiji =~ s/\r/
/g; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; # URL、E-mailが入力されていればリンクをつける if ($url ne "" || $mail ne "") { # どちらかに入力あり if ($url ne "" && $mail ne "") { # 両方あり print "ホームページ $name\n"; } if ($url ne "" && $mail eq "") { # URLのみあり print "ホームページ $name\n"; } if ($url eq "" && $mail ne "") { # Mailのみあり print "ホームページ $name\n"; } } else { # どちらも入力なし print "$name\n"; } print " $date
\n"; # 登録日付の表示 print "
$kiji
\n"; # 記事の表示 print "
\n"; print "
\n"; print "

"; } print "

\n"; print "\n"; exit; } ################################################################################ # データ書き込みルーチン sub data_put { if ($FORM{'name'} eq "") { # 名前の入力が無い &error_check(bad_name); # エラー処理へ } if ($FORM{'kiji'} eq "") { # 記事の入力が無い &error_check(bad_kiji); # エラー処理へ } if (!open(FILE, "$data_file")) { # データファイルを開く &error_check(bad_file); # エラーの時はメッセージを表示 } # チェックOKで書き込み if(&fusei_chk("$FORM{'name'}$FORM{'url'}$FORM{'mail'}$FORM{'kiji'}") != 1) { @DATA = ; # データを配列に格納 close(FILE); @DATA = reverse(@DATA); # 読み込みデータを新しい順にソート $data_count = @DATA; # 全ての件数を数える # 書き込みデータのフォーマット編集 $value = "$now_time\, $FORM{'name'}\, $FORM{'url'}\, $FORM{'mail'}\, $FORM{'kiji'}\n"; if ($data_count > ($data_max * 1.4)) { # データがリミットを越えたら $ins = $data_max - 1; # 処理する最大件数を保存 -1 は「押しちゃう」した分 foreach $kensu (@DATA) { # 新着順に並べ替え@TMPへ push (@TMP, $kensu); $ins--; # 処理カウンタを減算 if ($ins < 1) { # 全てを処理したらforeachを抜ける last; } } unshift (@TMP, $value); # 入力されたデータを@TMPの先頭に追加する @TMP = reverse(@TMP); # データファイルへ書く順番を整える(古い順にする) # データファイルを上書きモードで開く if (!open(FILE, ">$data_file")) { &error_check(bad_file); } # オープン失敗はエラー処理へ print FILE @TMP; # 全データを書き込む close (FILE); # データファイルを閉じる } else { # リミット越えてないので1件づつ書き込む # データファイルを追加モードで開く if (!open(FILE, ">>$data_file")) { &error_check(bad_file); } # オープン失敗はエラー処理へ print FILE $value; # ファイルの最後に書き込み close(FILE); # データファイルを閉じる } print "Location: $this_url" . '?' . "\n\n"; # リロード } else { # ワードチェック・エラー &error_check(bad_word); } } ################################################################################ # 不正ワードチェックルーチン sub fusei_chk { local ($str) = $_[0]; # 引数を取得 local ($match_flg) = 0; # ワード一致フラグ # チェックする言葉 $WORD[0] = 'エッチ'; $WORD[1] = 'SEX'; $WORD[2] = 'スケベ'; $WORD[3] = '死ね'; $WORD[4] = '呪い'; $WORD[5] = '殺す'; $WORD[6] = 'ブス'; foreach $check (@WORD) { # ワードチェック if (index($str, $check) >= 0) { # チェック文字と一致があったら $match_flg = 1; # ワード一致フラグを1にして last; # ただちに抜ける } } $match_flg; # ワード一致フラグを返す } ################################################################################ # エラー処理ルーチン sub error_check { $error_name = $_[0]; # 引数配列の先頭(エラー名)を確保 if ($error_name eq "bad_file") { # ファイル処理失敗 $msg = 'ファイルのオープンか入出力に失敗しました。'; } elsif ($error_name eq "bad_name") { # 名前未入力 $msg = '名前が入力されていません。'; } elsif ($error_name eq "bad_kiji") { # 記事未入力 $msg = '記事が入力されていません。'; } elsif ($error_name eq "bad_word") { # ワードチェック・エラー $msg = '不正な文字があります。'; } else { # 予期せぬエラー $msg = '予期せぬエラーが発生しました。'; } print "Content-type: text/html\n\n"; # メッセージの表示 print "サンプル BBS_1\n"; print "\n"; print "

\n"; print "

エラー


\n"; print "" . $msg . "
\n"; print "\n"; exit; # 終了しちゃう }