#!/usr/bin/perl #投稿記事をファイルに最大数までファイルに保存 #設定数だけ、ページ単位に表示 #Eメールの記入があれば、表示欄のクリックメール起動 #URLの記入があれば、記事からリンク #削除キーがあれば、本人が削除可能 $ver = 'small BBS'; # バージョン情報 # 文字コード変換ライブラリ取り込み require './jcode.pl'; { # スクリプト名 $script = "./bbs.cgi"; # ログファイル名 $logfile = "./bbs.log"; # 設定ファイル $setfile = "./bbs.ini"; # method形式 (POST/GET) $method = 'POST'; # タグ許可 (0=no 1=yes) $tagkey = 0; # URLの自動リンク (0=no 1=yes) $autolink = 1; # ホスト名取得方式 # 1 : gethostbyaddr関数で取得 $gethostbyaddr = 0; #$ENV{'REQUEST_METHOD'}='GET'; #$ENV{'QUERY_STRING'}="mode=update&name=mito&no=7&comment=567"; #設定ファイルで初期設定する &set_file; #FORM の解析 &decode; if ($mode eq 'regist') { ®ist; } if ($mode eq 'usrdel') { &usrdel; } if ($mode eq 'update') { &usrdel;®ist; } #掲示板のページを生成 &html; } # 設定処理 # sub set_file { # 設定ファイル読み込み # open(IN,"$setfile") || &error("Open Error : $setfile"); $data = ; close(IN); ($title,$t_color,$t_size,$ImgT,$bg,$bc,$tx,$lk,$vl,$al,$face,$b_size,$sub_color, $max,$home,$p_log,$deny,$mailto) = split(/<>/, $data); # ポイント数 $t_size .= 'pt'; $s_size = ($b_size - 1) . 'pt'; $b_size .= 'pt'; } # 記事表示処理 # sub html { &header; print "
\n"; # タイトル if ($ImgT) { print "\"$title\"\n"; } else { print "$title\n"; } print <<"EOM";
[トップに戻る] [投稿する] [管理用]
EOM #記事の表示開始 # ページ区切り処理 $start = $in{'page'} + 1; $end = $in{'page'} + $p_log; #startからendページまで表示 open(IN,"$logfile") || &error("Open Error : $logfile"); $i=0; while ($line=) { local($temp) = $xx; $i++; if ($i < $start) { next; } if ($i > $end) { last; } ($no,$date,$name,$mail,$sub,$com,$url,$host,$pw) = split(/<>/,$line); if ($mail) { $name = "$name"; } if ($url) { $url = "http://$url"; } # URL自動リンク if ($autolink) { &auto_link($com); } print "
[$no] $sub\n"; print "投稿者:$name 投稿日:$date
\n"; print "
$com

$url

\n"; #編集ボタン print "
\n"; print "\n"; print "\n"; print "
\n"; } #記事表示終了 close(IN); $next_page = $in{'page'} + $p_log; $back_page = $in{'page'} - $p_log; #前のページボタン print "
\n"; if ($back_page >= 0) { print "\n"; } #次のページボタン if ($next_page < $i) { print "\n"; } #削除ボタン print "
\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "\n"; print "記事No\n"; print "削除キー\n"; print "\n"; print "
\n"; exit; } # 書きこみ処理 (送信ボタン) sub regist { # フォーム内容をチェック #print "*****redist******\n"; if ($in{'name'} eq "" || $in{'comment'} eq "" ) { &error("名前または記事が入力されていません"); } if ($in{'pwd'} eq "") { &error("パスワードが入力されていません"); } open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); ($tno,$tdate,$tname,$tmail,$tsub,$tcom) = split(/<>/, $lines[0]); if ($in{'name'} eq "$tname" && $in{'comment'} eq "$tcom") { &error("同じ記事です"); } #投稿サイトのIPを取得する &get_host(); # 記事番号を増加 $no = $tno + 1; # 削除キーを設定 if ($in{'pwd'} ne "") { $PW = $in{'pwd'}; } # 最大記事数以上なら最後の記事を削除後、記事を追加 while ($max <= @lines) { pop(@lines); } unshift(@lines,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$PW<>\n"); #記事配列をファイルに書き出す open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @lines; close(OUT); #利用者情報をクッキーに記録する &set_cookie; } # 書き込み者による記事削除 # sub usrdel { #print "****usedel*****\n"; open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); $flag=0; @new=(); foreach (@lines) { ($no,$date,$name,$mail,$sub,$com,$url,$host,$pw) = split(/<>/); if ($in{'no'} eq "$no") { $flag=1; $PWD=$pw; } else { push(@new,$_); } } if ($flag == 0) { &error("該当記事が見当たりません"); } # 削除キーを照合 if ($in{'pwd'} ne "$PWD") { &error("パスワードが違います"); } # ログを更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); } #----------------# # FORM 入力解析 # #----------------# sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @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; # S-JISコード変換 &jcode'convert(*value,'sjis'); # タグ処理 if ($tagkey) { $value =~ s/<>/<>/g; } else { $value =~ s/&/&/g; $value =~ s//>/g; } # 改行処理 if ($name eq "comment") { $value =~ s/\r\n/
/g; $value =~ s/\r/
/g; $value =~ s/\n/
/g; } else { $value =~ s/\r//g; $value =~ s/\n//g; } # 削除情報 if ($name eq 'del') { push(@DEL,$value); } $in{$name} = $value; } $mode = $in{'mode'}; $in{'url'} =~ s/^http\:\/\///; if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } # 日時の取得 $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time); # 日時のフォーマット @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); $date = sprintf("%04d/%02d/%02d(%s) %02d:%02d", $year+1900,$mon+1,$mday,$week[$wday],$hour,$min); } #--------------# # HTMLヘッダ # #--------------# sub header { $head_flag = 1; print "Content-type: text/html\n\n"; print <<"EOM"; $title EOM } #--------------# # エラー処理 # sub error { # if ($lockkey) { &unlock; } &header if (!$head_flag); print "

ERROR !

\n"; print "

$_[0]\n"; print "


\n"; print "\n"; exit; } #----------------# # ホスト名取得 # sub get_host { $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($gethostbyaddr) { if ($host eq "" || $host eq "$addr") { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2); } } if ($host eq "") { $host = $addr; } } # クッキーの発行 # sub set_cookie { ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg) = gmtime(time + 60*24*60*60); @mons = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $date_g = sprintf("%s, %02d\-%s\-%04d %02d:%02d:%02d GMT", $week[$wdayg],$mdayg,$mons[$mong],$yearg+1900,$hourg,$ming,$secg); $cook="name\:$in{'name'}\,email\:$in{'email'}\,url\:$in{'url'}\,pwd\:$in{'pwd'}"; print "Set-Cookie: nBBS=$cook; expires=$date_g\n"; } #--------------# # 自動リンク # #--------------# sub auto_link { $_[0] =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\=\@\;\#\:\%]+)/$1$2<\/a>/g; }