#! /usr/bin/perl # # ↑このパスを環境に合わせて変更してください。 ##################################################################### # # 簡易電子掲示板 v1.11 # # (c)2004 by CGI RESCUE # http://www.rescue.ne.jp/ # # [履歴] # 2004/JAN/14 v1.00 リリース # 2004/FEB/03 v1.01 ページ処理バグ修正・改行有効設定の追加 他 # 2004/FEB/24 v1.10 タイトル一覧設定の追加 # 2004/SEP/03 v1.11 → HTML記述ミスを修正 # ##################################################################### #-------------------------------------------------------------------- # ▽改行を受け付けるかどうかの設定です。 # 0 を設定すると改行を無効にします。携帯風のこの掲示板のデザイン上、この設定が推奨です。 # 1 を設定すると改行を有効にします。本文フォームの右端および任意の改行位置で改行します。設定変更しても、この設定で # 投稿したものは改行表示されます。(データには改行位置にCR(\r)コードが記録されるため、UNIXサーバ以外に動作するかどうかは分かりませんし、 # データの修正時はUNIXエディタ以外ではファイルが壊れる可能性があります。) # # コラム ☆ 設定1の場合、英文字は単語(区切りに半角スペースが入る)単位で分離されて適度な改行位置が決まるため、連絡した文字では # ブラウザが自動で入れる改行が入りません。これはブラウザの特性によるものです。日本語の連続文字はその限りではありません。 $br = 0; #-------------------------------------------------------------------- # ▽掲示板の幅の設定です。 # %またはピクセルで設定してください。これは確実にその幅を保つということではありません。 $width = '50%'; #-------------------------------------------------------------------- # ▽タイトル制 # タイトルと本文を分離するかどうかの設定です。する場合は 1 しない場合は 0 に設定します。 $titleMode = 0; #-------------------------------------------------------------------- # ▽ブラウザの上部バーに表示するタイトルです。 # お気に入りにする場合の名前にもなります。 $bar_title = '掲示板'; #-------------------------------------------------------------------- # ▽文字、背景、リンクなどの色を設定するタグです。 # タグの詳細な設定方法は参考書などをご覧ください。 $body = ''; #-------------------------------------------------------------------- # ▽掲示板上部に表示するメッセージです。 # $head = <<'EOF'; の下から EOF の上までの間にHTML書式で記述します。 $head = <<'EOF';
掲示板
EOF #-------------------------------------------------------------------- # ▽掲示板から抜ける先のリンクを記入します。 # 掲示板上では "HOME" という部分にリンクされます。 $home = 'http://あなたのホームページなど/'; #-------------------------------------------------------------------- # ▽管理キー(マスターキー)の設定です。 # このパスワードにより任意の投稿の削除が可能になります。 # ' 'の間に半角英数字で指定してください。 $admin = 'masterkey'; #-------------------------------------------------------------------- # ▽記録ログ数の上限の設定です。 # 投稿がこの件数を超えたら、古いものから自動削除されていきます。 # 推奨値は 100 です。過度に大きな数字を設定しないでください。 $max = 100; #-------------------------------------------------------------------- # ▽1画面に一覧する投稿の数です。 # この数ずつページを変えることができます。 $page = 15; #-------------------------------------------------------------------- # ▽投稿の色設定です。 # $bodyColor は本文の色、$nameColor は名前と日付の色、$titleColor は題名の色です。 # ' 'の間に、#RGBまたはHTMLで扱える色名で指定してください。 $bodyColor = '#335588'; $nameColor = '#996699'; $titleColor = '#000000'; #------------------------------------------------------------------------------------------------- # ここから下はプログラミングが出来る方が必要に応じて編集してご利用ください。 #------------------------------------------------------------------------------------------------- # 日本語コード変換ライブラリ require './jcode.pl'; # 時刻設定 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); # (秒,分,時,日,月(0〜11),年(年号-1900),曜日(0〜6),1月1日から何日目,サマータイムの有無) @wday_array = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); @mon_array = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $timeStamp = sprintf("'%02d/%s/%01d %s %02d:%02d",$year -100,$mon_array[$mon],$mday,$wday_array[$wday],$hour,$min); $time = time; # アクセス情報 $addr = $ENV{'REMOTE_ADDR'}; if ($host eq "" || $host eq $addr) { $host = gethostbyaddr(pack('C4',split(/\./,$addr)),2) || $addr; } $via = $ENV{'HTTP_VIA'}; $xfor = $ENV{'HTTP_X_FORWARDED_FOR'}; $for = $ENV{'HTTP_FORWARDED'}; if ($for eq "") { $for = "-"; } $agent = $ENV{'HTTP_USER_AGENT'}; $agent =~ s//)/g; if ($via ne "") { $trueip = $xfor; } else { $trueip = $addr; $via = "-"; } if ($xfor ne "") { $xfor_name = gethostbyaddr(pack('C4',split(/\./,$xfor)),2) || $xfor; $xfor = "\[$xfor\]"; } else { $xfor_name = "-"; } $host_check = "$host\[$addr\] trueip:$trueip via:$via for:$for xfor:$xfor_name$xfor"; # # データ入力 # if ($ENV{'QUERY_STRING'} ne "") { # クエリー入力 @pairs = split(/&/,$ENV{'QUERY_STRING'}); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $value =~ s/\r//g; $value =~ s/\n//g; $value =~ s/\f//g; $value =~ s/\t//g; $value =~ s/\.//g; $value =~ s/\///g; $cmd{$name} = $value; } $cmd = $cmd{'cmd'}; } else { read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); # 標準入力 @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'h2z_sjis(*value); &jcode'convert(*value,'sjis'); if (!$br) { $value =~ s/\r//g; $value =~ s/\n//g; } else { $value =~ s/\r\n/\r/g; $value =~ s/\n//g; } $value =~ s/\f//g; $value =~ s/\t//g; if ($value !~ /&#(\d\d\d\d\d);/) { $value =~ s/&/&/g; } $value =~ s/"/"/g; $value =~ s//>/g; $in{$name} = $value; } $cmd = $in{'cmd'}; } # # 分岐 # if ($admin eq "") { $err = "マスターキーが設定されていません"; } if ($cmd eq "add" || $cmd eq "del") { $err = &FILE; &TOP; &FORM; &LIST; &BOTTOM; } else { &TOP; &FORM; &LIST; &BOTTOM; } # # 出力(上) # sub TOP { # エラーメッセージ if ($jcode'version < 2) { $err = "バージョン2以降のjcode.plを設置してください"; } if ($err) { $errmessage = "
$err
\n"; } print <<"EOF"; Content-type: text/html; charset=Shift_JIS\n $bar_title $body EOF if ($titleMode) { print "\n"; } print <<"EOF";
$head $errmessage EOF } # # 出力(フォーム) # sub FORM { $wrap = "タグ無効"; if (!$br) { $wrap .= "・改行無効"; } print <<"EOF";
名前
題名
本文
  ← 削除キー
EOF } # # 一覧処理 # sub LIST { if (open(F, "./data.cgi")) { @BASE = ; close(F); } else { return; } if (!@BASE) { print "\n"; return; } # 投稿なし # ページ処理↓ if ($cmd{'ff'} eq '') { $FF = 0; } else { $FF = $cmd{'ff'}; } $TO = $FF + $page - 1; if ($TO > $#BASE) { $TO = $#BASE; } $hit = 0; foreach $num ($FF .. $#BASE) { $filename = $BASE[$num]; if ($hit < $page) { $hit++; push(@DATA,$filename); } } $allhits = @BASE; $cmd{'allhits'} = $allhits; $count_new = @DATA; if ($cmd{'vp'} eq "") { $cmd{'vp'} = 1; } $n = $vp = 0; for ($jump = $page; $jump < $cmd{'allhits'} + $page; $jump += $page) { $vp++; $last_page++; } $start = $cmd{'vp'} - 4; if ($start < 1) { $start = 1; } $end = $cmd{'vp'} + 4; if ($end >= $last_page) { $end = $last_page; } $ffv = ($last_page - 1) * $page; $n = $vp = 0; foreach $vp ($start .. $end) { if ($vp == $cmd{'vp'}) { $page_now = $vp; last; } } $FROM = $page_now * $page - ($page - 1); $LAST = $FROM + $count_new - 1; print <<"EOF";
EOF } # # ファイル操作 # sub FILE { if ($cmd eq "add") { # 投稿 return "名前を入力してください" if $in{'uname'} eq ""; return "名前は全角なら15文字(30バイト)以内で" if length($in{'uname'}) > 30; return "題名を入力してください" if $in{'subject'} eq ""; return "名前は全角なら25文字(50バイト)以内で" if length($in{'subject'}) > 50; return "本文を入力してください" if $in{'body'} eq ""; return "本文は全角なら1000文字(2000バイト)以内で" if length($in{'body'}) > 2000; return "削除キーを入力してください" if $in{'pwd'} eq ""; return "削除キーは4〜8文字で" if length($in{'pwd'}) < 4 || length($in{'pwd'}) > 8; return "削除キーは英数字で" if $in{'pwd'} =~ /\W/; $pwd = &CRYPT($in{'pwd'}); # 暗号化 } elsif ($cmd eq "del") { # 削除 return "投稿したときの削除キーを入力してください" if $in{'key'} eq ""; } if (open(F, "+< ./data.cgi")) { flock F, 2; while () { s/\n//g; ($CODE,$DATE,$NAME,$SUBJECT,$BODY,$PWD,$HOST) = split(/\t/,$_,7); if ($cmd eq "del" && $CODE eq $in{'num'}) { # 削除 if (crypt($in{'key'},$PWD) eq $PWD || $in{'key'} eq $admin) { $d = "削除しました"; next; } else { close(F); return "削除キーが合いませんでした"; } } push(@BASE,"$_\n"); } eval 'truncate F,0;'; # truncate()が使えないサーバでは致命的なエラーとなる seek(F,0,0); if ($cmd eq "add") { unshift(@BASE,"$time\t$timeStamp\t$in{'uname'}\t$in{'subject'}\t$in{'body'}\t$pwd\t$host_check\n"); # 投稿 if ($#BASE > $max - 1) { $limit = $max - 1; } # $max行まで保存する else { $limit = $#BASE; } foreach $i (0..$limit) { print F $BASE[$i]; } } else { print F @BASE; } close(F); undef %in; if ($cmd eq "del" && $d ne "") { return $d; } else { return 0; } } else { return "'data.cgi'の設置が正しくされていません"; } } # # 暗号化 # sub CRYPT { my $pass = $_[0]; srand(); my @saltset = ('a'..'z','A'..'Z','0'..'9','.','/'); my $nsalt = $saltset[int(rand(64))] . $saltset[int(rand(64))]; return crypt($pass, $nsalt); }