#!/usr/bin/perl #┌───────────────────────────────── #│ YY-BOARD v4.6 (2002/08/01) #│ Copyright(C) Kent Web 1997-2002 #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── $ver = 'YYBBS v4.6'; #┌───────────────────────────────── #│ [注意事項] #│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した #│ いかなる損害に対して作者は一切の責任を負いません。 #│ 2. 設置に関する質問はサポート掲示板にお願いいたします。 #│ 直接メールによる質問は一切お受けいたしておりません。 #│ 3. 添付の home.gif は L.O.V.E の mayuRin さんによる画像です。 #└───────────────────────────────── # # 【ファイル構成例】 # # public_html (ホームディレクトリ) # | # +-- yybbs / yybbs.cgi [755] # | yybbs.log [666] # | count.dat [666] # | jcode.pl [644] # | pastno.dat [666] # | # +-- img / home.gif, bear.gif, ... # | # +-- lock [777] / # | # +-- past [777] / 1.dat [666] ... #============# # 設定項目 # #============# # 文字コードライブラリ取込 require '../jcode.pl'; # タイトル名を指定 $title = "掲示板"; # タイトルの色 $t_color = "#FF0000"; # タイトルの大きさ(ポイント数:スタイルシートで有効) $t_size = '18pt'; # タイトル文字のフォントタイプ $t_face = "MS Pゴシック"; # 本文の文字大きさ(ポイント数:スタイルシートで有効) $b_size = '11pt'; # 背景色を指定 $bgcolor = "#FFFFFF"; # 文字色を指定 $text = "#000000"; # リンク色を指定 $link = "#0000FF"; # 未訪問 $vlink = "#800080"; # 訪問済 $alink = "#FF0000"; # 訪問中 # 戻り先のURL (index.htmlなど) $homepage = "../index.html"; # 最大記事数 $max = 100; # 管理者用マスタパスワード (英数字で8文字以内) $pass = 'death666'; # アイコン画像のある「ディレクトリ」 # → フルパスなら http:// から記述する # → 最後は必ず / で閉じる $imgurl = "./img/"; # 管理者専用アイコン機能 (0=no 1=yes) # → 【使い方】記事投稿時に「管理者アイコン」を選択し、パスワードに # 「管理用パスワード」を入力して下さい。 $my_icon = 0; # 管理者専用アイコンの「ファイル名」を指定 $my_gif = 'admin.gif'; # アイコンモード (0=no 1=yes) $icon_mode = 0; # 返信がつくと親記事をトップへ移動 (0=no 1=yes) $topsort = 1; # ファイルロック形式 # → 0=no 1=symlink関数 2=mkdir関数 $lockkey = 2; # ロックファイル名 $lockfile = './lock/yybbs.lock'; # ミニカウンタの設置 # → 0=no 1=テキスト 2=GIF画像 $counter = 0; # ミニカウンタの桁数 $mini_fig = 6; # テキストのとき:ミニカウンタの色 $cnt_color = "#DD0000"; # GIFのとき:画像までのディレクトリ # → 最後は必ず / で閉じる $gif_path = "./img/"; $mini_w = 8; # 画像の横サイズ $mini_h = 12; # 画像の縦サイズ # カウンタファイル $cntfile = './count.dat'; # スクリプトのファイル名 # → フルパスで指定する場合は http:// から記述 $script = './yybbs.cgi'; # ログファイルを指定 # → フルパスで指定する場合は / から記述 $logfile = './yybbs.log'; # メールアドレスの入力必須 (0=no 1=yes) $in_email = 0; # 記事 [タイトル] 部の長さ (全角文字換算) $sub_len = '18'; # 記事の [タイトル] 部の色 $sub_color = "#FF0000"; # 記事表示部の下地の色 $tbl_color = "#FFFFFF"; # 家アイコンの使用 (0=no 1=yes) $home_icon = 1; $home_gif = "home.gif"; # 家アイコンのファイル名 $home_wid = 16; # 画像の横サイズ $home_hei = 20; # 〃 縦サイズ # イメージ参照画面の表示形態 # 1 : JavaScript # 2 : HTML (JavaScriptが不安定なブラザが多い場合はこちら) $ImageView = 1; # イメージ参照画面のサイズ (JavaScriptの場合) $img_w = 550; # 横幅 $img_h = 450; # 高さ # 記事の更新は method=POST 限定 (0=no 1=yes) # → セキュリティ対策 $MethPost = 1; # 同一IPアドレスからの連続投稿時間(秒数) # → 連続投稿などの荒らし対策 # → 値を 0 にするとこの機能は無効になります $wait = 60; # 1ページ当たりの記事表示数 (親記事) $p_log = 5; # 投稿があるとメール通知する (sendmail必須) # 0 : 通知しない # 1 : 通知するが、自分の投稿記事はメールしない。 # 2 : 通知する。自分の投稿記事も通知する。 $mailing = 1; # メールアドレス(メール通知する時) $mailto = 'luca@beyondnetwork.com'; # sendmailパス(メール通知する時) $sendmail = '/usr/sbin/sendmail'; # 他サイトから投稿排除時に指定 (http://から書く) $base_url = ""; # 文字色の設定。 @COLORS = ('FF0000','FF0099','FF5500','FF8040','FF00FF','FF66FF','FF99FF','660066','8A2BE2','CC66FF','0000FF','006699','3399FF','33CCCC','008040','00AA00','00FF00','339999','CC6633','800000','808080','003399','000080','505050'); # 投稿フォーム改行形式 (soft=手動 hard=強制) $wrap = 'soft'; # URLの自動リンク (0=no 1=yes) $autolink = 1; # ヘッダーファイル $headerfile = '../header.html'; #============# # 設定完了 # #============# # メイン処理 &decode; if ($mode eq "find") { &find; } elsif ($mode eq "usr_del") { &usr_del; } elsif ($mode eq "usr_edt") { &usr_edt; } elsif ($mode eq "regist") { ®ist; } elsif ($mode eq "res") { &res_form; } elsif ($mode eq "admin") { &admin; } elsif ($mode eq "check") { ✓ } &html_log; ################## ヘッダー表示 #################### sub header { print "Content-type: text/html\n\n"; open (OUT, "$headerfile") || &error("ヘッダーファイルが開けませんでした"); while () { print $_; } close(OUT); EOM } ################## フッター表示 #################### sub footer { print "\n"; print "\n"; print "\n\n"; } #--------------# # 記事表示部 # #--------------# sub html_log { local($no,$reno,$date,$name,$mail, $sub,$comment,$url,$host,$pw,$color,$icon,$p_flag); # クッキーを取得 &get_cookie; # フォーム長を調整 &get_agent; # ヘッダを出力 &header; # タイトル部 print "
\n"; print "
サポート掲示板
\n"; print <<"EOM";
EOM # 管理者アイコンを配列に付加 if ($my_icon) { push(@icon1,"$my_gif"); push(@icon2,"管理者用"); } if ($icon_mode) { print "\n"; } print "\n"; print "\n"; print "
おなまえ
Eメール
題  名  
コメント
URL
イメージ (あなたのイメージを選択して下さい)\n"; # イメージ参照のリンク if ($ImageView == 1) { print "[画像イメージ参照]"; } else { print "[画像イメージ参照]"; } print "
パスワード\n"; print "(記事のメンテ時に使用。英数字で8文字以内)
文字色\n"; # クッキーの色情報がない場合 if ($c_color eq "") { $c_color = $COLORS[0]; } $i=0; foreach (0 .. $#COLORS) { $i++; if ($i== 13) { print "
\n"; } if ($c_color eq "$COLORS[$_]") { print ""; print "\n"; } else { print ""; print "\n"; } } print "
\n"; print "

\n"; # ページ区切り処理 $start = $page + 1; $end = $page + $p_log; # 記事を展開 open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; $i=0; $flag=0; while () { ($no,$reno,$date,$name,$mail,$sub, $comment,$url,$host,$pw,$color,$icon) = split(/<>/); if ($reno eq "") { $i++; } if ($i < $start) { next; } if ($i > $end) { next; } # 題名の長さ if (length($sub) > $sub_len*2) { $sub = substr($sub,0,$sub_len*2); $sub .= "..."; } if ($mail) { $name = "$name"; } if ($home_icon && $url) { $url = "HomePage"; } elsif (!$home_icon && $url) { $url = "<HOME>"; } if (!$icon_mode) { $comment = "
$comment
"; } if (!$reno && $flag) { print "

\n"; $flag=1; } if (!$reno) { print "
\n"; $flag=1; } if ($reno) { print "
\n"; } print "\n"; if ($reno) { print ""; } print ""; print "\n"; } else { print "
\n"; } print "

$sub "; if (!$reno) { print "投稿者:$name 投稿日:$date "; } else { print "$name - $date "; } print "No\.$no   $url \n"; if (!$reno) { print "
\n"; print "\n"; print "\n"; print "
\n"; if ($reno) { print "\n"; } # アイコンモード if ($icon_mode) { print ""; } print "

\"$icon\"$comment
\n"; } close(IN); print "
\n"; $next_page = $page + $p_log; $back_page = $page - $p_log; $p_flag=0; print "

\n"; if ($back_page >= 0) { $p_flag=1; print "\n"; } if ($next_page < $i) { $p_flag=1; print "\n"; } # ページ移動ボタン表示 if ($p_flag) { print "\n"; } print "
\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
[直接移動]\n"; $x=1; $y=0; while ($i > 0) { if ($page == $y) { print "[$x]\n"; } else { print "[$x]\n"; } $x++; $y = $y + $p_log; $i = $i - $p_log; } print "
\n
\n"; print "
\n"; print "- 以下のフォームから自分の投稿記事を修正・削除することができます -
\n"; print "処理 \n"; print "記事No \n"; print "パスワード \n"; print "
\n"; # 著作権表示部 # MakiMakiさんの画像使用の有無に関わらずこの2箇所のリンク部の # 削除改変を禁止します print "$banner2

\n"; print "- KENT & "; print "MakiMaki -\n"; print "

\n"; &footer; exit; } #----------------# # ログ書込処理 # #----------------# sub regist { local(@lines,@new,@tmp,$top,$no,$ip,$time2,$no2,$reno2, $date2,$name2,$mail2,$sub2,$com2,$flag,$ango,$stop,$match); # フォーム入力チェック &form_check; # 時間を取得 &get_time; # ホストを取得 &get_host; # クッキーを発行 &set_cookie; # ファイルロック if ($lockkey) { &lock; } # ログを開く open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); # 記事NO処理 $top = shift(@lines); ($no,$ip,$time2) = split(/<>/, $top); $no++; # 連続投稿チェック if ($addr eq $ip && $wait > $times - $time2) { &error("連続投稿はもうしばらく時間をおいて下さい"); } # URL自動リンク if ($autolink) { &auto_link($in{'comment'}); } # 重複チェック $flag=0; foreach (@lines) { ($no2,$reno2,$date2,$name2,$mail2,$sub2,$com2) = split(/<>/); if ($in{'name'} eq $name2 && $in{'comment'} eq $com2) { $flag=1; last; } } if ($flag) { &error("重複投稿のため処理を中断しました"); } # パスワードを暗号化 if ($in{'pwd'} ne "") { $ango = &encrypt($in{'pwd'}); } # 親記事の場合 if ($in{'reno'} eq "") { $i=0; $stop=0; foreach (@lines) { ($no2,$reno2) = split(/<>/); $i++; if ($i > $max-1 && $reno2 eq "") { $stop=1; } if (!$stop) { push(@new,$_); } elsif ($stop && $pastkey) { push(@data,$_); } } unshift(@new,"$no<><>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$ango<>$in{'color'}<>$in{'icon'}<>\n"); unshift(@new,"$no<>$addr<>$times<>\n"); # 過去ログ更新 if ($data[0]) { &pastlog; } # 更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); } # レス記事の場合:トップソートあり elsif ($in{'reno'} && $topsort) { $match=0; @new=(); @tmp=(); foreach (@lines) { ($no2,$reno2) = split(/<>/); if ($in{'reno'} eq "$no2") { $match=1; push(@new,$_); } elsif ($in{'reno'} eq "$reno2") { push(@new,$_); } elsif ($match == 1 && $in{'reno'} ne "$reno2") { $match=2; push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$ango<>$in{'color'}<>$in{'icon'}<>\n"); push(@tmp,$_); } else { push(@tmp,$_); } } if ($match == 1) { push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$ango<>$in{'color'}<>$in{'icon'}<>\n"); } push(@new,@tmp); # 更新 unshift(@new,"$no<>$addr<>$times<>\n"); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); } # レス記事の場合:トップソートなし else { $match=0; @new=(); foreach (@lines) { ($no2,$reno2) = split(/<>/); if ($match == 0 && $in{'reno'} eq "$no2") { $match=1; } elsif ($match == 1 && $in{'reno'} ne "$reno2") { $match=2; push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$ango<>$in{'color'}<>$in{'icon'}<>\n"); } push(@new,$_); } if ($match == 1) { push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$ango<>$in{'color'}<>$in{'icon'}<>\n"); } # 更新 unshift(@new,"$no<>$addr<>$times<>\n"); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); } # ロック解除 if ($lockkey) { &unlock; } # メール処理 if ($mailing == 1 && $in{'email'} ne $mailto) { &mail_to; } elsif ($mailing == 2) { &mail_to; } } #----------------# # 返信フォーム # #----------------# sub res_form { local($no,$reno,$date,$name,$mail,$sub,$com,$url,$resub); # フォーム長を定義 &get_agent; # クッキーを取得 &get_cookie; # ログを読み込み open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; # ヘッダを出力 &header; # 関連記事出力 print "- 以下は、記事NO. $in{'no'} に関する返信フォームです -
\n"; print "
\n"; while () { ($no,$reno,$date,$name,$mail,$sub,$com,$url) = split(/<>/); if ($in{'no'} == $no || $in{'no'} == $reno) { if (length($sub) > $sub_len*2) { $sub = substr($sub,0,$sub_len*2-4); $sub .= "..."; } if ($in{'no'} == $no) { $resub = $sub; } if ($url) { $url = "<HOME>"; } if ($reno) { print '  '; } print "$sub 投稿者:$name 投稿日:$date $url No\.$no
\n"; print "
$com

\n"; } } close(IN); # タイトル名 if ($resub !~ /^Re\:/) { $resub = "Re\: $resub"; } print <<"EOM";
EOM # 管理者アイコンを配列に付加 if ($my_icon) { push(@icon1,"$my_gif"); push(@icon2,"管理者用"); } if ($icon_mode) { print "\n"; } print "\n"; print "
おなまえ
Eメール
タイトル
メッセージ
URL
イメージ\n"; if ($ImageView == 1) { print "[画像イメージ参照]"; } else { print "[画像イメージ参照]"; } print "
パスワード"; print "\n"; print "(自分の記事を削除時に使用。英数字で8文字以内)
文字色\n"; # クッキーの色情報がない場合 if ($c_color eq "") { $c_color = $COLORS[0]; } $i=0; foreach (0 .. $#COLORS) { $i++; if ($i== 13) { print "
\n"; } if ($c_color eq "$COLORS[$_]") { print ""; print "\n"; } else { print ""; print "\n"; } } print "
\n"; print "
\n"; &footer; exit; } #----------------# # デコード処理 # #----------------# sub decode { local($buffer, @pairs, $name, $value); $post_flag=0; if ($ENV{'REQUEST_METHOD'} eq "POST") { $post_flag=1; if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます"); } read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach (@pairs) { ($name,$value) = split(/=/); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # 文字コードをシフトJIS変換 &jcode'convert(*value, "sjis", "", "z"); # タグ処理 $value =~ s/&/&/g; $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'}; $page = $in{'page'}; $in{'url'} =~ s/^http\:\/\///; if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } } #---------------------------------# # ブラウザを判断:フォーム幅調整 # #---------------------------------# sub get_agent { # ブラウザ名を取得 $agent = $ENV{'HTTP_USER_AGENT'}; if ($agent =~ /MSIE 3/i) { $nam_wid = 30; $sub_wid = 40; $com_wid = 65; $url_wid = 48; $nam_wid2 = 20; } elsif ($agent =~ /MSIE (4|5|6)/i) { $nam_wid = 30; $sub_wid = 38; $com_wid = 60; $url_wid = 60; $nam_wid2 = 20; } else { $nam_wid = 20; $sub_wid = 25; $com_wid = 56; $url_wid = 50; $nam_wid2 = 10; } } #------------------# # クッキーの発行 # #------------------# sub set_cookie { # クッキーは60日間有効 local($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime(time+60*24*60*60); @month=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", $week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec); $cook="name<>$in{'name'}\,email<>$in{'email'}\,url<>$in{'url'}\,pwd<>$in{'pwd'}\,icon<>$in{'icon'}\,color<>$in{'color'}"; print "Set-Cookie: YYBBS=$cook; expires=$gmt\n"; } #------------------# # クッキーを取得 # #------------------# sub get_cookie { local($key, $val, @pairs); @pairs = split(/;/, $ENV{'HTTP_COOKIE'}); foreach (@pairs) { ($key,$val) = split(/=/); $key =~ s/\s//g; $GET{$key} = $val; } @pairs = split(/,/, $GET{'YYBBS'}); foreach (@pairs) { ($key,$val) = split(/<>/); $COOK{$key} = $val; } $c_name = $COOK{'name'}; $c_email = $COOK{'email'}; $c_url = $COOK{'url'}; $c_pwd = $COOK{'pwd'}; $c_icon = $COOK{'icon'}; $c_color = $COOK{'color'}; if ($in{'name'}) { $c_name = $in{'name'}; } if ($in{'email'}) { $c_email = $in{'email'}; } if ($in{'url'}) { $c_url = $in{'url'}; } if ($in{'pwd'}) { $c_pwd = $in{'pwd'}; } if ($in{'icon'}) { $c_icon = $in{'icon'}; } if ($in{'color'}) { $c_color = $in{'color'}; } } #--------------# # エラー処理 # #--------------# sub error { if ($lockflag) { &unlock; } &header if (!$head_flag); print "

ERROR !

\n"; print "

$_[0]\n"; print "


\n"; &footer; exit; } #--------------# # 管理モード # #--------------# sub admin { local($dmy,$no,$reno,$date,$name,$mail,$sub, $com,$url,$host,$pw,$next_page,$back_page); if ($in{'pass'} ne "" && $in{'pass'} ne $pass) { &error("パスワードが違います"); } &header; print "[掲示板に戻る]\n"; print "
\n"; print "管理モード\n"; print "
\n"; if ($in{'pass'} eq "") { print "

パスワードを入力して下さい

\n"; print "
\n"; print "\n"; print "\n"; print ""; print "
\n"; } else { # 削除処理 if ($DEL[0]) { # ロック処理 if ($lockkey) { &lock; } # 削除情報をマッチングし更新 @new=(); open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { $flag=0; ($no,$reno,$date) = split(/<>/); foreach $del (@DEL) { if ($no == $del || $reno == $del) { $flag=1; last; } } if ($flag == 0) { push(@new,$_); } } close(IN); # 更新 unshift(@new,$top); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # ロック解除 if ($lockkey) { &unlock; } } # 管理を表示 if ($page eq "") { $page = 0; } print "

\n"; print "
  • 削除する記事のチェックボックスにチェックを入れ、削除ボタンを押して下さい。\n"; print "
  • 親記事を削除するとレス記事も一括して削除されます。
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print ""; print "\n"; print "

\n"; print ""; print "\n"; # ページ区切り処理 $start = $page + 1; $end = $page + $p_log; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; $i=0; while () { ($no,$reno,$date,$name,$mail,$sub,$com,$url,$host,$pw) = split(/<>/); if ($reno eq "") { $i++; } if ($i < $start) { next; } if ($i > $end) { last; } if ($mail) { $name="$name"; } ($date,$dmy) = split(/\(/, $date); if ($url) { $url = "<Home>"; } else { $url = '-'; } $com =~ s/
//ig; $com =~ s//>/g; if (length($com) > 40) { $com = substr($com,0,38); $com .= "..."; } if ($reno eq "") { print "
\n"; } # 削除チェックボックス print ""; print ""; print ""; print ""; print "\n"; } close(IN); print "\n"; print "
削除記事NO投稿日タイトル投稿者URLコメントホスト名

$no$date$sub$name$url$com$host

\n"; } $next_page = $page + $p_log; $back_page = $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 "\n"; print "\n"; print "\n"; print "

\n"; &footer; exit; } #------------------# # ユーザ記事削除 # #------------------# sub usr_del { local(@lines,@new,$no,$reno,$dt,$name,$mail,$sub,$com,$url,$host,$pw,$top,$PW); # POST限定 if ($MethPost && !$post_flag) { &error("不正なアクセスです"); } if ($in{'no'} eq '' || $in{'pwd'} eq '') { &error("記事Noまたはパスワードが入力モレです"); } # ロック処理 if ($lockkey) { &lock; } open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); $top = shift(@lines); $flag=0; foreach (@lines) { ($no,$reno,$dt,$name,$mail,$sub,$com,$url,$host,$pw) = split(/<>/); if ($flag == 0 && $in{'no'} == $no) { $PW = $pw; if ($reno eq "") { $flag=2; } else { $flag=1; } } elsif ($flag == 2 && $in{'no'} == $reno) { next; } else { push(@new,$_); } } if ($flag == 0) { &error("該当記事が見当たりません"); } if ($PW eq '') { &error("該当記事にはパスワードが設定されていません"); } # パスワードを照合 $match = &decrypt("$in{'pwd'}","$PW"); if ($match ne 'yes') { &error("パスワードが違います"); } # 更新 unshift(@new,$top); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # ロック解除 if ($lockkey) { &unlock; } } #----------------# # 記事修正処理 # #----------------# sub usr_edt { local($no,$reno,$dt,$name,$mail,$sub,$com, $url,$host,$pw,$color,$icon,$flag,$top,$flag,$pattern); if ($in{'no'} eq '' || $in{'pwd'} eq '') { &error("記事Noまたはパスワードが入力モレです"); } if ($in{'action'} eq "edit") { # フォーム入力チェック &form_check; # ロック処理 &lock if ($lockkey); } $flag=0; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { ($no,$reno,$dt,$name,$mail,$sub,$com,$url,$host,$pw,$color,$icon) = split(/<>/); if ($in{'no'} == $no) { $pw2 = $pw; $flag=1; if ($in{'action'} ne "edit") { last; } else { if ($autolink) { &auto_link($in{'comment'}); } $_ = "$no<>$reno<>$dt<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pw<>$in{'color'}<>$in{'icon'}<>\n"; } } if ($in{'action'} eq "edit") { push(@new,$_); } } close(IN); if (!$flag) { &error("該当の記事が見当たりません"); } if ($pw2 eq "") { &error("パスワードが設定されていません"); } $check = &decrypt("$in{'pwd'}", "$pw2"); if ($check ne "yes") { &error("パスワードが違います"); } if ($in{'action'} eq "edit") { unshift(@new,$top); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); &unlock if ($lockkey); &set_cookie; if ($in{'url'}) { $in{'url'} = "http://$in{'url'}"; } if ($in{'email'}) { $in{'email'} = "$in{'email'}"; } &header; print "
\n"; print "- 以下のとおり修正が完了しました -\n"; print "

\n"; print "お名前:$in{'name'}
\n"; print "メール:$in{'email'}
\n"; print "題 名:$in{'sub'}
\n"; print "URL:$in{'url'}

\n"; print "本 文:$in{'comment'}\n"; print "

\n"; print "

\n"; print "
\n"; print "
\n\n\n"; exit; } &get_agent; $com =~ s/
/\r/g; $pattern = 'http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+'; $com =~ s/($pattern)<\/a>/$1/go; &header; print <<"EOM"; - 変更する部分のみ修正して送信ボタンを押して下さい -

EOM # 管理者アイコンを配列に付加 if ($my_icon) { push(@icon1,"$my_gif"); push(@icon2,"管理者用"); } if ($icon_mode) { print "\n"; } print "
おなまえ
Eメール
題  名
コメント
URL
イメージ (あなたのイメージを選択して下さい)\n"; # イメージ参照のリンク if ($ImageView == 1) { print "[画像イメージ参照]"; } else { print "[画像イメージ参照]"; } print "
文字色\n"; $i=0; foreach (0 .. $#COLORS) { $i++; if ($i== 13) { print "
\n"; } if ($color eq "$COLORS[$_]") { print ""; print "\n"; } else { print ""; print "\n"; } } print "
\n"; &footer; exit; } #------------------------# # フォーム入力チェック # #------------------------# sub form_check { local($ref_url); # POST限定 if ($MethPost && !$post_flag) { &error("不正なアクセスです"); } # 他サイトからのアクセスを排除 if ($base_url) { $ref_url = $ENV{'HTTP_REFERER'}; $ref_url =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($ref_url !~ /$base_url/i) { &error("不正なアクセスです"); } } # 名前とコメントは必須 if ($in{'name'} eq "") { &error("名前が入力されていません"); } if ($in{'comment'} eq "") { &error("コメントが入力されていません"); } if ($in_email && $in{'email'} !~ /[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,3}/) { &error("Eメールの入力内容が正しくありません"); } # 管理アイコンのチェック if ($my_icon && $in{'icon'} eq $my_gif) { if ($in{'pwd'} ne $pass) { &error("管理用アイコンは管理者専用です"); } } } #--------------# # 時間を取得 # #--------------# sub get_time { $ENV{'TZ'} = "JST-9"; $times = time; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($times); @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); } #--------------# # ロック処理 # #--------------# sub lock { local($retry,$mtime); # 1分以上古いロックは削除する if (-e $lockfile) { ($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { &unlock; } } # symlink関数式ロック if ($lockkey == 1) { $retry = 5; while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } # mkdir関数式ロック } elsif ($lockkey == 2) { $retry = 5; while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } } $lockflag=1; } #--------------# # ロック解除 # #--------------# sub unlock { if ($lockkey == 1) { unlink($lockfile); } elsif ($lockkey == 2) { rmdir($lockfile); } $lockflag=0; } #--------------# # メール送信 # #--------------# sub mail_to { local($MailSub,$MailBody,$email); # メールタイトルを定義 $MailSub = "[$title : $no] $in{'sub'}"; # 記事の改行を復元 $com = $in{'comment'}; $com =~ s/
/\n/g; # メール本文を定義 $MailBody = <<"EOM"; 投稿日時:$date ホスト名:$host ブラウザ:$ENV{'HTTP_USER_AGENT'} 投稿者名:$in{'name'} Eメール:$in{'email'} URL :$in{'url'} タイトル:$in{'sub'} 投稿記事: $com EOM # JISコード変換 &jcode'convert(*MailSub,'jis'); &jcode'convert(*MailBody,'jis'); # メールアドレスがない場合 if ($in{'email'} eq "") { $email = $mailto; } else { $email = $in{'email'}; } open(MAIL,"| $sendmail -t") || &error("メール送信に失敗しました"); print MAIL "To: $mailto\n"; print MAIL "From: $email\n"; print MAIL "Subject: $MailSub\n"; print MAIL "MIME-Version: 1.0\n"; print MAIL "Content-type: text/plain; charset=ISO-2022-JP\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "X-Mailer: $ver\n\n"; print MAIL "--------------------------------------------------------\n"; print MAIL "$MailBody\n"; print MAIL "--------------------------------------------------------\n"; close(MAIL); } #----------------------# # パスワード暗号処理 # #----------------------# sub encrypt { local($inpw) = $_[0]; local(@SALT, $salt, $encrypt); @SALT = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); srand; $salt = $SALT[int(rand(@SALT))] . $SALT[int(rand(@SALT))]; $encrypt = crypt($inpw, $salt) || crypt ($inpw, '$1$' . $salt); return $encrypt; } #----------------------# # パスワード照合処理 # #----------------------# sub decrypt { local($inpw, $logpw) = @_; local($salt, $key, $check); $salt = $logpw =~ /^\$1\$(.*)\$/ && $1 || substr($logpw, 0, 2); $check = "no"; if (crypt($inpw, $salt) eq $logpw || crypt($inpw, '$1$' . $salt) eq $logpw) { $check = "yes"; } return $check; } #-----------------# # 自動URLリンク # #-----------------# sub auto_link { $_[0] =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1
$2<\/a>/g; } #----------------# # ホスト名取得 # #----------------# sub get_host { $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($host eq "" || $host eq "$addr") { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr; } } #-----------------# # URLエンコード # #-----------------# sub url_enc { local($_) = @_; s/(\W)/'%' . unpack('H2', $1)/eg; s/\s/+/g; $_; }