タイトル

掲示板全解説ページです。
説明は多少不親切かも・・・
参考程度に。


#!/usr/local/bin/perl

#↑perlのパスを指定する。
# サーバでCGIを動かすプログラムを指定します。
# これがちゃんと指定されてないと当然動きません。と

#####↓初期設定↓################################################################

# 日本語変換用プログラム。
# 日本語を文字化けしないで使用できる賢いやつ。
require './jcode.pl';

# CGIの名前を指定する。
$script = "bbss.cgi";
# 書き込むLOGファイルを指定。
$logfile = "bbss.log";

# BODY設定
$body = '<body bgcolor="#eeffee">';

# タイトルの色
$titlecolor ="#0000ff";
# LOGを表示する背景色
$tablecolor = "#ffffee";
# タイトルと時間の背景色
$tr1color = "#eeffff";
# 名前とホストを表示する背景色
$tr2color = "#ffeeff";

# タイトルが未記入だった時、この文字に置き換える
$notitle = "No Title";

# 掲示板の最大LOG保存数(これ以上になると古い順に削除)
$max = "30";

#####↑初期設定終了↑############################################################


# デコード処理(日本語の文字コードを解析して、読めるように変換する)
# FORMからの投稿を正しく読めるようにするのに必要な処理です。
# 必須のおまじないみたいなものだと思ってください。
if($ENV{'REQUEST_METHOD'} eq "POST"){
	read(STDIN, $QUERY, $ENV{'CONTENT_LENGTH'}); 
}else{
	$QUERY = $ENV{'QUERY_STRING'};
}

@QUERY = split(/&/,$QUERY);
foreach (@QUERY){
	($n,$v)=split(/=/);
	$v =~ tr/+/ /;
	$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# ここまでは必須のおまじない。
# 細かい説明は省かせていただきます。

# 以下は特殊文字に変換します。
# 理由は、CGI内部で特殊文字を制御文字として使うことがあり、
# そのまま使うとエラーになる可能性があるからです。

	# 「&」をHTMLの特殊文字&amp;に変換する。
	$v =~ s/&/&amp;/g;
	# 「"」をHTMLの特殊文字&quot;に変換する。
	$v =~ s/"/&quot;/g;
	# 「\t」(タブコード)を半角スペースにする
	$v =~ s/\t/ /g;
	# 改行コードをタグの改行(<br>)に変換。
	# 三つあるのは、winは「\r\n」、Macは「\r」、unixは「\n」と改行コードが違うからです。
	# どんなOSから投稿されても正しく変換されるようにしています。
	$v =~ s/\r\n/<br>/g;
	$v =~ s/\r/<br>/g;
	$v =~ s/\n/<br>/g;

	# タグの山カッコ「<」「>」をHTMLの特殊文字「&lt;」と「&gt;」に変換する。
	# いわゆるタグの使用を禁止。
	$v =~ s/</&lt;/g;
	$v =~ s/>/&gt;/g;

	# 文字コードを「jcode.pl」の力を借りて「S-JIS」に変換します。
	&jcode'convert(*v,'sjis');

	# 入力されたFORMからのデータを$FORM{xxx}(xxxはnameで指定した文字)
	# という形式に置き換える
	$FORM{$n} = $v;

}

	# よく使う変数はめんどくさくないのに置き換える
	$mode = $FORM{'mode'};

	# もし$mode が reg (書込みモード)だったら
	if ($mode eq "reg") {
		# もし名前がなかったら $er にエラー文字を入れる
		if ($FORM{'name'} eq "") { $er = "名前を書いてよぉ。\n"; }
		# もしコメントがなかったら $er にエラー文字を入れる
		if ($FORM{'com'} eq "") { $er = "コメントくらい書いてよぉ\n"; }

		# もしエラー文字がなかったら(空白だったら)書き込み処理
		# &xxx;は、サブルーチンにワープ。サブルーチンを処理したらここに戻ってくる。
		if($er eq "") { ® }
	}

# HTMLを表示させるにはContent-typeを指定しないといけない。
# HTMLを表示させるおまじないです。
print "Content-type: text/html\n\n";

####################
#■#ヘッダー情報#■#

# print "\n"; でHTMLを指定。
# ちなみに「\n」は改行コード。なくても普通に表示されますが、ソースが見づらくなります。
print "<html>\n";
print "<head>\n";
print "<title>けいじばん</title>\n";
print "</head>\n";
# 上で指定したBODYを書き込む
print "$body\n";

	# もしエラー文字がなかったら掲示板のタイトルを入れる
	if ($er eq "") { print "掲示板だよーん♪\n"; }
	# そうじゃなかったら(エラー文字があったら)エラー文字に置き換える
	else { print "$er\n"; }

################
#■#投稿FORM#■#


# print<<"HTML";で複数行のHTMLを指定する。
# 次に現れるHTMLという文字までを書き出す。
# HTMLという文字は変えてもOKです。
# ちなみに、print<<HTML;でも平気。
# print<<'HTML';でも平気ですが、これだと変数($xxxとか)が置き換わらなくなります。

# ちなみにvalue指定をしてあるのは、入力NGだった時に入力項目が消えないようにするためです。
print<<"HTML";
<form action="$script" method="POST">
<input type="hidden" name="mode" value="reg">
名前:<input type="text" name="name" value="$FORM{'name'}">
<br>メール:<input type="text" name="mail" value="$FORM{'mail'}">
<br>URL:<input type="text" name="url" size="30" value="$FORM{'url'}">
<br>タイトル:<input type="text" name="title" value="$FORM{'title'}">
<br>コメント
<br><textarea name=com cols="80" rows="5">$FORM{'com'}</textarea>
<input type="submit" value="書き込みましょうか">
</form>
<center>
HTML

# pirnt""; で挟む時、この中で「"」を使うと、
# そこまでが書き出す情報だと認識してしまい、エラーが起こります。
# それを防ぐ為に「"」の前に「\」をつけて、区切りの「"」じゃなくて、
# 文字としての「"」だと指定します。
# もしくは、「'」で囲う
print "<table border=\"0\" bgcolor=\"$tablecolor\" width='80%'>\n";
# 「'」で囲ってもいいけども、変数が置き換わらない。また、「\n」もそのまま表示される。
print ' <tr>';
print "\n  <td>\n";

print "<hr>\n";

#####################
#■#LOGを表示する#■#

	# ファイルを開ける。「IN」というファイルハンドルで、
	# $logfileというファイル(上で指定したファイル)を開ける。
	open(IN, "$logfile");
	# <IN>の中にあるものを繰り返して、全部処理する。
	# 本当はwhileはカッコの中が正の場合繰り返すという意味です。
	# ちょっと亜流の使い方なんで。
	while (<IN>) {
		# 読み込んだ情報をカンマ「,」で分けます。
		# 分けた情報は左から
		# $title,$name,$mail,$url,$com,$host,$data
		# という変数にぶち込まれます。
		($title,$name,$mail,$url,$com,$host,$data) = split(/\,/);

# LOGを表示します。
print<<"HTML";

<table border="0" width="100%">
 <tr bgcolor="$tr1color">
  <th>
   <font size="+1" color="$titlecolor">$title</font>
  </th>
  <td>
   <font size="-1">$data</font>
  </td>
 </tr>
 <tr bgcolor="$tr2color">
  <td align="center">
	
HTML

		# メール、URL処理

		# メールが""(空白)ではなくて、URLが""(空白) ではないとき(メールもURLもある時)
		if (($mail ne "") && ($url ne "")){
			# メールをmailtoに入れ、名前にリンクする。URLをホームページという文字にリンクする
			print "<a href=\"mailto:$mail\"><font size=\"+1\">$name</font></a> <a href=\"$url\"><font size=\"-1\">ホームページ</font></a>\n";
		# メールが""(空白)ではなくて、URLが"" (空白)のとき(メールだけある時)
		}elsif (($mail ne "") && ($url eq "")){
			# メールをmailtoに入れ、名前にリンクする。URLは処理しない
			print "<a href=\"mailto:$mail\"><font size=\"+1\">$name</font></a>\n";
		# メールが""(空白)で、URLが"" (空白)ではないとき(URLだけもある時)
		}elsif (($mail eq "") && ($url ne "")){
			# URLをホームページという文字にリンクする
			print "<font size=\"+1\">$name</font> <font size=\"-1\"><a href=\"$url\">ホームページ</a></font>\n";
		# 上記以外のとき(メールが""(空白)で、URLが"" (空白)のとき(どちらともない時))
		}else{
			print "<font size=\"+1\">$name</font>\n";
		}

# 残りのデータを表示
print<<"HTML";
	
  </td>
  <td>
   <font size="-1">$host</font>
  </td>
 </tr>
 <tr>
  <td colspan="2">
   $com
  </td>
 </tr>
</table>

<hr>

HTML
	
	}
	# 開けたら閉じる
	close(IN);

# HTML書き込む
print "  </td>\n";
print " </tr>\n";
print "</table>\n";
print "</center>\n";

############################
#■#フッター/著作権情報#■#

# print qq||; という形でも書き出せる。
# qq で書式指定。区切り文字を指定できます。別に|の変わりに/でやってもOKです。
# もちろん不便ですけども。普段使わない文字で区切れば使いやすいです。
print qq|<p align="right">\n|;
print qq/<font size="-1">\n/;
print qq|<a href="http://mawashimono.com/web/">HPの回し者</a>\n|;
print qq|</font>\n|;
print qq|</p>\n|;

print qq|</body>\n|;
print qq|</html>\n|;

# このCGIを終了させます。
# 途中でもexit; があれば終了します。
exit;

####################
#■#書き込み処理#■#

# サブルーチンで指定。sub xxx{ .. } という指定。
# どこかで&xxx;と指定してやると、中身..を処理する。
sub reg {

# 時間を取る。
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
# 年は1900年から取るので、四桁にする為に+1900する
$year = $year+1900;
# 月は0〜11を取るので、+1をしてやる。
$mon = $mon+1;

# 分数が一桁だと見づらいので、一桁だった場合、左に0を足す
if ($min < 10) { $min="0$min"; }
# 曜日を指定する
@youbi = ('日曜', '月曜', '火曜', '水曜', '木曜', '金曜', '土曜');
# 書込みデータの書式設定。
$data = "$year年$mon月$mday日($youbi[$wday])$hour時$min分";

	# もしタイトルがなかった場合、上で指定した文字に置き換える
	if ($FORM{'title'} eq ""){ $FORM{'title'} = "$notitle"; }

	# ホスト名を取る。(サーバによって取れないことが良くある)
	$host = $ENV{'REMOTE_HOST'};

	# もしホスト名が取れなかったら
	if ($host eq "") {
		# IPアドレスを取る
		$addr = $ENV{'REMOTE_ADDR'};
		# IPアドレスをホスト名にする秘密の呪文
		$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2);
	}

# 開く
open(IN,"$logfile");
# 中身を読み込む
@lines = <IN>;
# 開いたら閉じる
close(IN);

	# 書き込み数チェック
	# 最大書込み数より書き込まれている数が多ければ下から消す
	while ($max <= @lines) { pop(@lines); }

# @linesの一番上に次の文字列を入れる。
unshift(@lines,"$FORM{'title'},$FORM{'name'},$FORM{'mail'},$FORM{'url'},$FORM{'com'},$host,$data\n");
# 書込みモードで開く
open(OUT,">$logfile");
# @linesを書き込む
print OUT @lines;
# もちろん開けたら閉じる
close(OUT);

# valueでFORMに残らないようにタイトルの中身を消す
$FORM{'title'} = "";
# valueでFORMに残らないようにコメントを消す
$FORM{'com'} = "";

}


わかってるとは思いますが、CGIの改造は個々の責任においてやってください。
なにかがあって、私に責任を追及されても困りますから。

表紙に行く