#!/usr/local/bin/perl $ver = 'YYBBS v4.8+'; #┌───────────────────────────────── #│ YY-BOARD v4.8 (2003/01/10) #│ Copyright(C) Kent Web 2003 #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── # タイトル名を指定 $title = ""; # 戻り先のURL (index.htmlなど) $homepage = ""; # 投稿後の処理 # → 掲示板自身のURLを記述しておくと、投稿後リロードします # → ブラウザを再読み込みしても二重投稿されない措置。 # → Locationヘッダの使用可能なサーバのみ $location = ''; #┌───────────────────────────────── #│ [注意事項] #│ 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] ... # # 補足 # ver.1.06 から追加された「特定文字列置換機能」は # 設定:276〜287行目付近 # ルーチン呼び出し:667〜670行目付近 # サブルーチン本体:2462〜2509行目付近 # # 使い方は、辞書ファイル(デフォルトでは dic.txt)に # 「,」区切りで「置換前,置換後,」といったフォーマットで記述 # 置換許可文字(デフォルトでは「!」)を指定したあとに # 置換前の文字列を指定することにより # 置換後の文字列に置換される仕組み # この機能を搭載するに辺り、毎回毎回助けて頂いている # もりばさん(ぽあぞんでずゅー:http://www32.tok2.com/home/moriba/)多謝 #============# # 設定項目 # #============# # 文字コードライブラリ取込 require './jcode.pl'; # タイトルの色 $t_color = "#FFFFCC"; # タイトルの大きさ(ポイント数:スタイルシートで有効) $t_size = '18pt'; # タイトル文字のフォントタイプ $t_face = "MS Pゴシック"; # 本文の文字大きさ(ポイント数:スタイルシートで有効) $b_size = '10pt'; # 壁紙を指定する場合(http://から指定) $backgif = ""; # 背景色を指定 $bgcolor = "#000000"; # 文字色を指定 $text = "#FFFFFF"; # リンク色を指定 $link = "#00FFFF"; # 未訪問 $vlink = "#FF00FF"; # 訪問済 $hlink = "#FFFFFF"; # カーソールを重ねている状態 $hbglink = "#0033CC"; # カーソールを重ねている状態のバックグラウンド # 最大記事数 $max = 60; # 管理者用マスタパスワード (英数字で8文字以内) $pass = ''; # アイコン画像のある「ディレクトリ」 # → フルパスなら http:// から記述する # → 最後は必ず / で閉じる $imgurl = "./image_icon/"; # アイコングループ機能を使う (0=no 1=yes) $icon_group = 1; # アイコングループの最初のグループ名を記述する。 # 使わない場合は、空白 $first_group = "どこでもいっしょ"; # アイコンを定義(上下は必ずペアで) # icon1 にアイコングループ名を記述する場合、icon2 は空白になる。 @icon1 = ('ic_dokoitu_ju1.gif','ic_dokoitu_ju2.gif','ic_dokoitu_ju3.gif','ic_dokoitu_ju4.gif', 'ic_dokoitu_pi1.gif','ic_dokoitu_pi2.gif','ic_dokoitu_pi3.gif','ic_dokoitu_pi4.gif', 'ic_dokoitu_ri1.gif','ic_dokoitu_ri2.gif','ic_dokoitu_ri3.gif','ic_dokoitu_ri4.gif', 'ic_dokoitu_su1.gif','ic_dokoitu_su2.gif','ic_dokoitu_su3.gif','ic_dokoitu_su4.gif', 'ic_dokoitu_to1.gif','ic_dokoitu_to2.gif','ic_dokoitu_to3.gif','ic_dokoitu_to4.gif', 'age謹製君望アイコン','ic_age_legend1.gif','ic_age_legend2.gif','ic_age_legend3.gif', '伺か','ic_nani_sakura.png','ic_nani_unyu1.png','ic_nani_unyu2.png','ic_nani_nekoko.png', '君が望む永遠','ic_km_akane.png','ic_km_haruka.png','ic_km_mitsuki.png','ic_km_ayu.png','ic_km_mayu.png', 'マブラヴ','ic_ml_sumika.png','ic_ml_meiya.png','ic_ml_kei.png','ic_ml_chizuru.png','ic_ml_miki.png','ic_ml_akane.png', 'ic_ml_tsukuyomi.png','ic_ml_kasumi.png','ic_ml_takeru.png','ic_ml_mikoto.png', 'ギャラクシーエンジェル','ic_ga_mille.png','ic_ga_ranfa.png','ic_ga_mint.png','ic_ga_vanilla.png','ic_ga_forte.png','ic_ga_nomad.png', '月姫','ic_tuki_arc.png','ic_tuki_ciel.png','ic_tuki_akiha.png','ic_tuki_hisui.png','ic_tuki_kohaku.png','ic_tuki_sacchin.png', 'ic_tuki_ren.png','ic_tuki_akira.png','ic_tuki_hanepin.png','ic_tuki_souka.png','ic_tuki_nanako.png','ic_tuki_sion.png', '東京ミュウミュウ','ic_myu_ichigo.png','ic_myu_mint.png','ic_myu_lettuce.png','ic_myu_purin.png','ic_myu_zakuro.png', '.hack//黄昏の腕輪伝説','ic_hk_shuhgo.png','ic_hk_rena.png','ic_hk_mireille.png','ic_hk_ohka.png','ic_hk_hotaru.png', '小麦ちゃんマジカルて','ic_nw_komugi.png','ic_nw_koyori.png','ic_nw_mugimaru.png', 'はじめての○○','ic_hajime_shiori.png','ic_hajime_saori.png','ic_hajime_yuuna.png','ic_hajime_maina.png', 'マリア様がみてる','ic_mm_yumi.png','ic_mm_sachiko.png','ic_mm_yohko.png','ic_mm_yoshino.png','ic_mm_rei.png','ic_mm_eriko.png', 'ic_mm_noriko.png','ic_mm_shimako.png','ic_mm_sei.png','ic_mm_shizuka.png','ic_mm_tsutako.png','ic_mm_tohko.png', 'ic_mm_minako.png','ic_mm_mami.png','ic_mm_syohko.png', 'SNOW','ic_sn_sumino.png','ic_sn_shigure.png','ic_sn_ohka.png','ic_sn_meiko.png','ic_sn_asahi.png','ic_sn_hohsen.png', 'その他','ic_another_bridget.png','ic_another_mahoro.png','ic_another_minawa.png','ic_another_nadja.png','black.gif'); @icon2 = ('ジュン','ジュン驚く','ジュン喜ぶ','ジュン泣く', 'ピエ〜ル','ピエ〜ル喜ぶ','ピエ〜ルムフフ','ピエ〜ル困る', 'リッキ〜','リッキ〜喜ぶ','リッキ〜一息','リッキ〜困る', 'R.スズキ','R.スズキ喜ぶ','R.スズキ怒る','R.スズキため息', 'トロ','トロ喜ぶ','トロ泣く','トロ困る', '','100m長靴遙','溺れ遙','餌付け遙', '','さくら','うにゅう1','うにゅう2','ねここ', '','茜','遙','水月','あゆあゆ','まゆまゆ', '','純夏','冥夜','慧','千鶴','壬姫','茜', '月詠','霞','武','尊人', '','ミルフィーユ','蘭花','ミント','ヴァニラ','フォルテ','ノーマッド', '','アルクェイド','シエル','秋葉','翡翠','琥珀','さっちん', 'レン','晶','羽ピン','蒼香','ななこ','シオン', '','ミュウイチゴ','ミュウミント','ミュウレタス','ミュウプリン','ミュウザクロ', '','シューゴ','レナ','ミレイユ','凰花','ほたる', '','小麦','こより','むぎまる', '','しおりたん','さおりたん','ゆうなたん','まいなたん', '','祐巳','祥子','蓉子','由乃','令','江利子', '乃梨子','志摩子','聖','静','蔦子','瞳子', '三奈子','真美','笙子', '','雪月澄乃','北里しぐれ','桜花','橘 芽衣子','日和川 旭','鳳仙', '','ブリジットたん','まほろ','みなわ','ナージャ','アイコン無し'); # 管理者専用アイコン機能 (0=no 1=yes) # → 【使い方】記事投稿時に「管理者アイコン」を選択し、パスワードに # 「管理用パスワード」を入力して下さい。 $my_icon = 0; # 管理者専用アイコンの「ファイル名」を指定 $my_gif = 'admin.gif'; # アイコンモード (0=no 1=yes) $icon_mode = 1; # 返信がつくと親記事をトップへ移動 (0=no 1=yes) $topsort = 1; # タイトルにGIF画像を使用する時 (http://から記述) $title_gif = ""; $tg_w = 0; # GIF画像の幅 (ピクセル) $tg_h = 0; # 〃 高さ (ピクセル) # ファイルロック形式 # → 0=no 1=symlink関数 2=mkdir関数 $lockkey = 0; # ロックファイル名 $lockfile = './lock/yybbs.lock'; # ミニカウンタの設置 # → 0=no 1=テキスト 2=GIF画像 $counter = 1; # ミニカウンタの桁数 $mini_fig = 5; # テキストのとき:ミニカウンタの色 $cnt_color = "#FFFFFF"; # GIFのとき:画像までのディレクトリ # → 最後は必ず / で閉じる $gif_path = "./img/"; $mini_w = 0; # 画像の横サイズ $mini_h = 0; # 画像の縦サイズ # カウンタファイル $cntfile = './count.dat'; # スクリプトのファイル名 # → フルパスで指定する場合は http:// から記述 $script = './yybbs.cgi'; # ログファイルを指定 # → フルパスで指定する場合は / から記述 $logfile = './yybbs.log'; # メールアドレスの入力必須 (0=no 1=yes) $in_email = 0; # 記事 [タイトル] 部の長さ (全角文字換算) $sub_len = '25'; # 記事の [タイトル] 部の文字の大きさ $sub_size = '3'; # 記事の [タイトル] 部の色 $sub_color = "#FF0000"; # 記事表示部の下地の色 $tbl_color = "#000000"; # 家アイコンの使用 (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 = 800; # 横幅 $img_h = 600; # 高さ # 記事の更新は method=POST 限定 (0=no 1=yes) # → セキュリティ対策 $MethPost = 1; # 同一IPアドレスからの連続投稿時間(秒数) # → 連続投稿などの荒らし対策 # → 値を 0 にするとこの機能は無効になります $wait = 0; # 1ページ当たりの記事表示数 (親記事) $p_log = 15; # 投稿があるとメール通知する (sendmail必須) # 0 : 通知しない # 1 : 通知するが、自分の投稿記事はメールしない。 # 2 : 通知する。自分の投稿記事も通知する。 $mailing = 0; # メールアドレス(メール通知する時) $mailto = 'bee-x@msg.biglobe.ne.jp'; # sendmailパス(メール通知する時) $sendmail = '/usr/lib/sendmail'; # 他サイトから投稿排除時に指定 (http://から書く) $base_url = ""; # 文字色の設定。 # @COLORS = ('#800000','#DF0000','#008040','#0000FF','#C100C1','#FF80C0','#FF8040','#000080'); # URLの自動リンク (0=no 1=yes) # タグを有効に改造しているのでデフォルトで「0(no)」指定 $autolink = 0; # タグ広告挿入オプション # → の代わりに「広告タグ」を挿入する。 # → 広告タグ以外に、MIDIタグ や LimeCounter等のタグにも使用可能です。 $banner1 = ''; # 掲示板上部に挿入 $banner2 = ''; # 掲示板下部に挿入 # アクセス制限(ホスト名、IPアドレスを記述) @deny = ( "", "", "", "" ); # 特定単語の置換処理を行うか? (0=no 1=yes) $subst = 1; # 置換辞書ファイル $dic_file = './dic.txt'; # 置換許可文字(記号)の指定 # 指定しない場合は、無記入 # 記号(!"#$%&'()=~|@`[{;+:*]},<.>/?\_)を # 指定する場合は、「\」を追加する事。 # 例:「!」を指定する場合は「\!」と記述 $sign = "\!"; #---(以下は「過去ログ」機能を使用する場合の設定です)---# # # 過去ログ生成 (0=no 1=yes) $pastkey = 1; # 過去ログ用NOファイル $nofile = './pastno.dat'; # 過去ログのディレクトリ # → フルパスなら / から記述(http://からではない) # → 最後は必ず / で閉じる $pastdir = './past/'; # 過去ログ1ファイルの行数 # → この行数を超えると次ページを自動生成します $log_line = 600; #============# # 設定完了 # #============# # メイン処理 &decode; &axs_check; if ($mode eq "howto") { &howto; } elsif ($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 "image") { ℑ } elsif ($mode eq "past") { &past; } elsif ($mode eq "check") { ✓ } &html_log; #--------------# # 記事表示部 # #--------------# sub html_log { local($no,$reno,$date,$name,$mail,$sub,$comment,$url,$host,$agent,$pw,$icon,$p_flag,$fix_flag); # クッキーを取得 local($cnam,$ceml,$curl,$cpwd,$cico) = &get_cookie; # ヘッダを出力 if ($ImageView == 1) { &header('ImageUp'); } else { &header; } # カウンタ処理 if ($counter) { &counter; } # タイトル部 print "[Return to Top]\n"; print "[Usage]\n"; print "
\n"; if ($banner1 ne "") { print "$banner1

\n"; } if ($title_gif eq '') { print "$title\n"; } else { print "\"$title\"\n"; } 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 "\n"; print "\n"; # print "
Name
E-Mail
Title
Comment
URI
Icon (Icon Select)\n"; # イメージ参照のリンク if ($ImageView == 1) { print "[Refer to Icon]"; } else { print "[Refer to Icon]"; } print "
Password\n"; print "(The alphanumeric char of less than 8 char.)
 "; print "Correction / deletion of Shortcut
文字色\n"; # クッキーの色情報がない場合 # if ($ccol eq "") { $ccol = $COLORS[0]; } # foreach (0 .. $#COLORS) { # if ($ccol eq $COLORS[$_]) { # print ""; # print "\n"; # } else { # print ""; # print "\n"; # } # } print "
\n"; print "


\n"; # 記事を展開 open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; $i=0; $flag=0; while () { ($no,$reno,$date,$name,$mail,$sub,$comment,$url,$host,$agent,$pw,$icon,$fix_flag) = split(/<>/); if ($reno eq "") { $i++; } if ($i < $page + 1) { next; } if ($i > $page + $p_log) { 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"; print "\n"; } else { print "
\n"; } print "\n"; print "\n"; print "\n"; print "

No\.$no Title:$sub
$url \n"; if (!$reno) { print "
\n"; print "\n"; print "\n"; print "
\n"; print "
Name:$name Date:$date
\n"; if ($reno) { print "\n"; } # アイコンモード if ($icon_mode) { print ""; } # 通常時の文字色を設定している場所 print "

\"$icon\"$comment

\n"; print "$agent\n"; if ($fix_flag) { print " / この記事は $fix_flag回修正されています。"; } print "
\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 "
Direct >>\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 "
\n"; print "
\n"; print "Contribution report Correction / Deletion processing.\n"; print "Processing  \n"; print "No.  \n"; print "Password  \n"; print "\n"; print "
\n"; print "
\n"; print "[Word Reference]\n\n"; # 過去ログのリンク部を表示 if ($pastkey) { print "[Past log]\n"; } print "[Update]\n"; print "[Admin]\n"; print "
\n"; # フッダー出力 &fudder; exit; } #----------------# # ログ書込処理 # #----------------# sub regist { local($f,$top,$no,$ip,$time2,$no2,$reno2,$date2,$name2, $mail2,$sub2,$com2,$flag,$ango,$stop,$match,$agent,@lines,@new,@tmp,$fix_flag); # フォーム入力チェック &form_check; # 時間を取得 &get_time; # USER AGNET の取得 &get_agent; # クッキーを発行 &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 ($subst) { &substitute($in{'comment'}); } # パスワードを暗号化 if ($in{'pwd'} ne "") { $ango = &encrypt($in{'pwd'}); } # 修復カウント初期化 $fix_flag = 0; # 親記事の場合 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<>$agent<>$ango<>$in{'icon'}<>$fix_flag<>\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) { $f=0; $match=0; @new=(); @tmp=(); foreach (@lines) { ($no2,$reno2) = split(/<>/); if ($in{'reno'} eq $no2) { if ($reno2) { $f++; last; } $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<>$agent<>$ango<>$in{'icon'}<>$fix_flag<>\n"); push(@tmp,$_); } else { push(@tmp,$_); } } if ($f) { &error("不正な返信要求です"); } if ($match == 1) { push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$agent<>$ango<>$in{'icon'}<>$fix_flag<>\n"); } push(@new,@tmp); # 更新 unshift(@new,"$no<>$addr<>$times<>\n"); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # レス記事の場合:トップソートなし } else { $f=0; $match=0; @new=(); foreach (@lines) { ($no2,$reno2) = split(/<>/); if ($match == 0 && $in{'reno'} eq $no2) { if ($reno2) { $f++; last; } $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<>$agent<>$ango<>$in{'icon'}<>$fix_flag<>\n"); } push(@new,$_); } if ($f) { &error("不正な返信要求です"); } if ($match == 1) { push(@new,"$no<>$in{'reno'}<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$agent<>$ango<>$in{'icon'}<>$fix_flag<>\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; } # リロード if ($location) { if ($ENV{'PERLXS'} eq "PerlIS") { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $location?\n\n"; } else { &header; print "

\n"; print "

投稿は正常に処理されました

\n"; print "
\n"; print "
\n"; &fudder; } exit; } #----------------# # 返信フォーム # #----------------# sub res_form { local($f,$no,$reno,$date,$name,$mail,$sub,$com,$url,$resub); # クッキーを取得 local($cnam,$ceml,$curl,$cpwd,$cico) = &get_cookie; # ログを読み込み $f=0; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; # ヘッダを出力 if ($ImageView == 1) { &header('ImageUp'); } else { &header; } # 関連記事出力 print "- The following is the reply form about report No.$in{'no'}. -
\n"; print "[Reply is stopped]
\n"; while () { ($no,$reno,$date,$name,$mail,$sub,$com,$url) = split(/<>/); if ($in{'no'} == $no && $reno) { $f++; } 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 ($home_icon && $url) { $url = "HomePage"; } elsif (!$home_icon && $url) { $url = "<HOME>"; } if ($reno) { print '  '; } print "No\.$no ", "Title:$sub ", "Name:$name ", "Date:$date ", "$url
\n", # レスフォーム文字色:変更予定箇所開始 "
$com

\n"; # レスフォーム文字色:変更予定箇所終了 } } close(IN); if ($f) { &error("不正な返信要求です"); } # タイトル名 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 "\n"; print "\n"; # print "
Name
E-Mail
Title
Comment
URI
Icon (Icon Select)\n"; # イメージ参照用のリンク if ($ImageView == 1) { print "[Refer to Icon]"; } else { print "[Refer to Icon]"; } print "
Password"; print "\n"; print "(The alphanumeric char of less than 8 char.)
文字色\n"; # クッキーの色情報がない場合 # if ($ccol eq "") { $ccol = $COLORS[0]; } # foreach (0 .. $#COLORS) { # if ($ccol eq $COLORS[$_]) { # print ""; # print "\n"; # } else { # print ""; # print "\n"; # } # } print "
\n"; print "
\n"; &fudder; 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; $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'} = "No Title"; } } #----------------# # アクセス制限 # #----------------# sub axs_check { # ホスト名を取得 &get_host; local($flag)=0; foreach (@deny) { if (!$_) { next; } s/\*/\.\*/g; if ($host =~ /$_/i) { $flag=1; last; } } if ($flag) { &error("アクセスを許可されていません"); } } #------------# # 留意事項 # #------------# sub howto { &header; print <<"EOM"; [Return to BBS]
The cautions on use of BBS.

  1. この掲示板は cookie 対応です。1度記事を投稿いただくと、Name、E-Mail、URI、Password の情報は2回目以降は自動入力されます。(ただし利用者のブラウザが cookie 対応の場合)

  2. 記事を投稿する上での必須入力項目は「Name」と「Comment」です。E-Mail、URI、Title、Password は任意です。

  3. 記事には、半角カナは一切使用しないで下さい。文字化けの原因となります。

  4. 記事の投稿時に「Password」にパスワード(英数字で8文字以内)を入れておくと、その記事は次回パスワードによって削除することができます。

  5. 記事の保持件数は最大 $max件です。それを超えると古い順に過去ログに飛ばされます。

  6. 既存の記事に「返信」をすることができます。各記事の上部にある「Reply」ボタンを押すと返信用フォームが現れます。

  7. 過去の投稿記事から「キーワード」によって簡易検索ができます。トップメニューの「Word Reference」のリンクをクリックすると検索モードとなります。

  8. Bee-Xが著しく不利益と判断する記事、他人を誹謗中傷する記事、営利不営利関係なく商用に関する記事は、は予\告なく削除いたします。
EOM &fudder; exit; } #------------------# # ワード検索処理 # #------------------# sub find { local($no,$reno,$date,$name,$email,$sub,$com,$url); &header; print <<"EOM"; [Return to BBS]
Word Reference

  • 検索したいキーワードを入力し、「条件」「表\示」を選択して「検索」ボタンを押して下さい。
  • キーワードは「半角スペース」で区切って複数指定することができます。

    キーワード: 条件:\n 表\示:\n
\n"; # ワード検索の実行と結果表示 if ($in{'word'} ne ""){ # 入力内容を整理 $in{'word'} =~ s/ / /g; @pairs = split(/\s+/, $in{'word'}); # ファイルを読み込み @new=(); open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { $flag=0; foreach $pair (@pairs) { if (index($_,$pair) >= 0) { $flag=1; if ($in{'cond'} eq 'OR') { last; } } else { if ($in{'cond'} eq 'AND') { $flag=0; last; } } } if ($flag) { push(@new,$_); } } close(IN); # 検索終了 $count = @new; print "検索結果:$count件\n"; if ($page eq '') { $page = 0; } $end_data = @new - 1; $page_end = $page + $in{'view'} - 1; if ($page_end >= $end_data) { $page_end = $end_data; } $next_line = $page_end + 1; $back_line = $page - $in{'view'}; $eword = &url_enc($in{'word'}); if ($back_line >= 0) { print "[前の$in{'view'}件]\n"; } if ($page_end ne "$end_data") { print "[次の$in{'view'}件]\n"; } print "[検索やり直し]\n"; foreach ($page .. $page_end) { ($no,$reno,$date,$name,$email,$sub,$com,$url) = split(/<>/, $new[$_]); if ($email) { $name = "$name"; } if ($url) { $url = "<HOME>"; } if ($reno) { $no = "$renoへのレス"; } # 結果を表示 print "
No\.$no "; print "Title:$sub "; print "Name:$name "; print "Date:$date "; print "$url
\n"; print "
$com
\n"; } print "
\n"; } &fudder; exit; } #------------------# # クッキーの発行 # #------------------# sub set_cookie { local($gmt, $cook, @t, @m, @w); @t = gmtime(time + 60*24*60*60); @m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); @w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", $w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]); $cook="$in{'name'}<>$in{'email'}<>$in{'url'}<>$in{'pwd'}<>$in{'icon'}"; print "Set-Cookie: YY_BBS=$cook; expires=$gmt\n"; } #------------------# # クッキーを取得 # #------------------# sub get_cookie { local($key, $val, *ck); $ck = $ENV{'HTTP_COOKIE'}; foreach (split(/;/, $ck)) { ($key, $val) = split(/=/); $key =~ s/\s//g; $ck{$key} = $val; } @ck = split(/<>/, $ck{'YY_BBS'}); return (@ck); } #--------------# # エラー処理 # #--------------# sub error { if ($lockflag) { &unlock; } &header if (!$head_flag); print "

ERROR !

\n"; print "

$_[0]

\n"; print "[Return to BBS]\n"; print "

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

Enter Password

\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,$agent,$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 = '-'; } # タグ処理(許可しているので以下2行はコメント) $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.投稿日TitleNameURICommentHost

$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"; &fudder; exit; } #------------------# # ユーザ記事削除 # #------------------# sub usr_del { local(@lines,@new,$no,$reno,$dt,$name,$mail,$sub,$com,$url,$host,$agent,$pw,$icon,$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,$agent,$pw,$icon) = 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,$agent,$pw,$icon,$flag,$top,$flag,$pattern,$fix_flag); if ($in{'no'} eq '' || $in{'pwd'} eq '') { &error("記事No.またはパスワードが入力漏れです"); } if ($in{'action'} eq "edit") { # フォーム入力チェック &form_check; # ロック処理 if ($lockkey) { &lock; } } $flag=0; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { ($no,$reno,$dt,$name,$mail,$sub,$com,$url,$host,$agent,$pw,$icon,$fix_flag) = split(/<>/); # USER AGNET の再取得 &get_agent; # 修正回数のカウント $fix_flag++; 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<>$agent<>$pw<>$in{'icon'}<>$fix_flag<>\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); # ロック解除 if ($lockkey) { &unlock; } # クッキーを発行 &set_cookie; if ($home_icon && $url) { $url = "HomePage"; } elsif (!$home_icon && $url) { $url = "<HOME>"; } if ($in{'email'}) { $in{'email'} = "$in{'email'}"; } # メール処理 if ($mailing == 1 && $in{'email'} ne $mailto) { &mail_to; } elsif ($mailing == 2) { &mail_to; } # リロード if ($location) { if ($ENV{'PERLXS'} eq "PerlIS") { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $location?\n\n"; } else { &header; print "

\n"; print "

修正は正常に処理されました

\n"; print "
\n"; print "
\n"; print "
\n"; &fudder; } exit; } # クッキーを取得 local($cnam,$ceml,$curl,$cpwd,$cico) = &get_cookie; $com =~ s/
/\r/g; $pattern = 'http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+'; $com =~ s/($pattern)<\/a>/$1/go; if ($ImageView == 1) { &header('ImageUp'); } else { &header; } # 関連記事出力 print "- 以下は、記事No.$in{'no'} に関する修正フォームです -
\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 "\n"; print "\n"; print "
Name
E-Mail
Title
Comment
URI
Icon (Icon Select)\n"; # イメージ参照のリンク if ($ImageView == 1) { print "[Refer to Icon]"; } else { print "[Refer to Icon]"; } print "
文字色\n"; # foreach (0 .. $#COLORS) { # if ($color eq $COLORS[$_]) { # print ""; # print "\n"; # } else { # print ""; # print "\n"; # } # } print "
\n"; &fudder; 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,5}$/) { &error("E-Mailの入力内容が正しくありません"); } # 管理アイコンのチェック 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 counter { local($cntup,@cnts,$cnt); # 閲覧時のみカウントアップ if ($mode eq '') { $cntup=1; } else { $cntup=0; } # カウントファイルを読みこみ open(IN,"$cntfile") || &error("Open Error : $cntfile"); eval "flock(IN, 1);"; $data = ; close(IN); # IPチェックとログ破損チェック ($cnt, $ip) = split(/:/, $data); if ($addr eq $ip || $cnt eq "") { $cntup=0; } # カウントアップ if ($cntup) { $cnt++; open(OUT,"+< $cntfile") || &error("Write Error : $cntfile"); eval "flock(OUT, 2);"; truncate(OUT, 0); seek(OUT, 0, 0); print OUT "$cnt\:$addr"; close(OUT); } # 桁数調整 while(length($cnt) < $mini_fig) { $cnt = '0' . $cnt; } @cnts = split(//, $cnt); # GIFカウンタ表示 if ($counter == 2) { foreach (0 .. $#cnts) { print "\"$cnts[$_]\""; } } # テキストカウンタ表示 else { print "$cnt\n"; } } #--------------# # ロック処理 # #--------------# 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, $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; } #------------------# # HTMLのヘッダー # #------------------# sub header { $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; EOM # JavaScriptヘッダー if ($ImageView == 1 && $_[0] eq "ImageUp") { print "\n"; print "\n"; } print "$title\n"; print "\n"; print "\n"; print "\n"; } #------------------# # HTMLのフッダー # #------------------# sub fudder { # 著作権表示(削除不可) # → MakiMakiさんの画像を使用しない場合に限り、MakiMakiさんのリンクを外すことは可能 print "
\n"; print "
\n"; print "$banner2

\n"; print "- KENT & "; print "MakiMaki & "; print "age & "; print "Expensive Noise + "; print "Bee-X -\n"; print "

\n\n\n"; } #-----------------# # 自動URLリンク # #-----------------# sub auto_link { $_[0] =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1$2<\/a>/g; } #--------------------# # 画像イメージ表示 # #--------------------# sub image { local($i,$j,$stop); &header; print "

\n"; print "Icon image sample\n"; print "

- The icon image registered now is as follows. -\n"; print "


\n"; print "

\n"; # $i=0; $j=0; if ($icon_group) { print "\n"; $i = 1; $j = 0; } else { $i = 0; $j = 0; } $stop = @icon1; foreach (0 .. $#icon1) { $i++; $j++; print "\n"; if ($j != $stop && $i >= 5) { print "\n"; $i=0; } elsif ($j == $stop) { if ($i == 0) { last; } while ($i < 5) { print ""; $i++; } } } print "
$first_group\"$icon1[$_]\" $icon2[$_]


\n"; print "

\n"; print "
\n"; &fudder; exit; } #----------------# # ホスト名取得 # #----------------# 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; } } #----------------# # 過去ログ生成 # #----------------# sub pastlog { local($count,$pastfile,@temp,$pno,$preno,$pdate,$pname,$pmail,$psub,$pcom,$purl,$pho,$pagent); local($past_flag)=0; # 過去NOを開く open(NO,"$nofile") || &error("Open Error : $nofile"); $count = ; close(NO); # 過去ログのファイル名を定義 $pastfile = "$pastdir$count\.dat"; # 過去ログを開く open(IN,"$pastfile") || &error("Open Error : $pastfile"); @past = ; close(IN); # 規定の行数をオーバーすると次ファイルを自動生成 if ($#past > $log_line) { $past_flag=1; # カウントファイル更新 $count++; open(NO,">$nofile") || &error("Write Error : $nofile"); print NO $count; close(NO); $pastfile = "$pastdir$count\.dat"; @past=(); } @temp=(); foreach (@data) { ($pno,$preno,$pdate,$pname,$pmail,$psub,$pcom,$purl,$pho,$pagnet) = split(/<>/); if ($pmail) { $pname = "
$pname"; } if ($purl) { $purl = "<HOME>"; } if ($preno) { $pno = "$prenoへのレス"; } # 保存記事をフォーマット push(@temp,"
No\.$pno Title:$psub Name:$pname Date:$pdate $purl
$pcom
\n"); } # 過去ログを更新 unshift(@past,@temp); open(OUT,">$pastfile") || &error("Write Error : $pastfile"); print OUT @past; close(OUT); if ($past_flag) { chmod(0666,$pastfile); } } #------------# # 過去ログ # #------------# sub past { local($pastno,@new,$count,@pairs,$pair); open(IN,"$nofile") || &error("Open Error : $nofile"); $pastno = ; close(IN); if (!$in{'pastlog'}) { $in{'pastlog'} = $pastno; } &header; print <<"EOM"; [Return to BBS]
Past log[$in{'pastlog'}]

\n"; print "\n"; print "
Past log:\n
\n"; print "
\n"; print "\n"; print "\n"; print "Word Reference:\n"; print "Conditions:\n"; print "View:\n
\n"; # 表示ログを定義 $in{'pastlog'} =~ s/\D//g; $file = "$pastdir$in{'pastlog'}\.dat"; # ワード検索処理 if ($in{'word'} ne "") { $in{'word'} =~ s/ / /g; @pairs = split(/\s+/, $in{'word'}); @new=(); open(IN,"$file") || &error("Open Error : $file"); while () { $flag=0; foreach $pair (@pairs) { if (index($_,$pair) >= 0) { $flag=1; if ($in{'cond'} eq 'OR') { last; } } else { if ($in{'cond'} eq 'AND') { $flag=0; last; } } } if ($flag) { push(@new,$_); } } close(IN); $count = @new; print "Reference result:$count件\n"; if ($page eq '') { $page = 0; } $end_data = @new - 1; $page_end = $page + $in{'view'} - 1; if ($page_end >= $end_data) { $page_end = $end_data; } $next_line = $page_end + 1; $back_line = $page - $in{'view'}; $eword = &url_enc($in{'word'}); if ($back_line >= 0) { print "[Front$in{'view'}件]\n"; } if ($page_end ne "$end_data") { print "[Next$in{'view'}件]\n"; } print "[Reference redo]\n"; # 表示開始 foreach ($page .. $page_end) { print $new[$_]; } &fudder; exit; } # ページ区切り処理 $start = $page + 1; $end = $page + $p_log; $i=0; open(IN,"$file") || &error("Open Error : $file"); while () { $flag=0; if ($_ =~ /^\\[\d+\]/) { $flag=1; $i++; } if ($i < $start) { next; } if ($i > $end) { last; } if ($flag) { print $_; } else { $_ =~ s/


//ig; print "
$_
\n"; } } close(IN); print "
\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"; &fudder; exit; } #------------------# # チェックモード # #------------------# sub check { &header; print "

Check Mode

\n"; print "
    \n"; # ログパス if (-e $logfile) { print "
  • ログファイルのパス:OK\n"; } else { print "
  • ログファイルのパス:NG → $logfile\n"; } # ログパーミッション if (-r $logfile && -w $logfile) { print "
  • ログファイルのパーミッション:OK\n"; } else { print "
  • ログファイルのパーミッション:NG\n"; } # カウンタログ print "
  • カウンタ:"; if ($counter) { print "設定あり\n"; if (-e $cntfile) { print "
  • カウンタログファイルのパス:OK\n"; } else { print "
  • カウンタログファイルのパス:NG → $cntfile\n"; } } else { print "設定なし\n"; } # ロックディレクトリ print "
  • ロック形式:"; if ($lockkey == 0) { print "ロック設定なし\n"; } else { if ($lockkey == 1) { print "symlink\n"; } else { print "mkdir\n"; } ($lockdir) = $lockfile =~ /(.*)[\\\/].*$/; print "
  • ロックディレクトリ:$lockdir\n"; if (-d $lockdir) { print "
  • ロックディレクトリのパス:OK\n"; } else { print "
  • ロックディレクトリのパス:NG → $lockdir\n"; } if (-r $lockdir && -w $lockdir && -x $lockdir) { print "
  • ロックディレクトリのパーミッション:OK\n"; } else { print "
  • ロックディレクトリのパーミッション:NG → $lockdir\n"; } } # 過去ログ print "
  • 過去ログ:"; if ($pastkey == 0) { print "設定なし\n"; } else { print "設定あり\n"; # NOファイル if (-e $nofile) { print "
  • NOファイルパス:OK\n"; } else { print "
  • NOファイルのパス:NG → $nofile\n"; } if (-r $nofile && -w $nofile) { print "
  • NOファイルパーミッション:OK\n"; } else { print "
  • NOファイルパーミッション:NG → $nofile\n"; } # ディレクトリ if (-d $pastdir) { print "
  • 過去ログディレクトリパス:OK\n"; } else { print "
  • 過去ログディレクトリのパス:NG → $pastdir\n"; } if (-r $pastdir && -w $pastdir && -x $pastdir) { print "
  • 過去ログディレクトリパーミッション:OK\n"; } else { print "
  • 過去ログディレクトリパーミッション:NG → $pastdir\n"; } } print "
\n"; &fudder; exit; } #-----------------# # URLエンコード # #-----------------# sub url_enc { local($_) = @_; s/(\W)/'%' . unpack('H2', $1)/eg; s/\s/+/g; $_; } #---------------------# # USER_AGENT の取得 # #---------------------# sub get_agent { # ブラウザ名を取得 $agent = $ENV{'HTTP_USER_AGENT'}; } #--------------------# # 特定文字列置換処理 # #--------------------# # 変数内訳 # $conv_flag = 文字コード変換を行ったかどうかの判定 # $code = 元の文字コードの保持 # $dic_file = 置換文字列を記述した辞書ファイル # $rep_bef = 置換前文字列 # $rep_aft = 置換後文字列 # $sign = 置換許可文字(記号)の指定 sub substitute { # convert flag 初期化 $conv_flag = 0; # 投稿コメントの文字コードを調査 $code = &jcode'getcode(\$_[0]); # 投稿コメントを euc に変換 # 元の文字コードが euc ならばスルー if ( $code ne "euc" ) { $conv_flag = 1; &jcode'convert(\$_[0], "euc", $code); } # ファイルのオープン open(DIC,"$dic_file") || &error("Open Error : $dic_file"); while () { # 置換前,置換後文字列を分割して、 # 各変数に代入する。 ($rep_bef,$rep_aft) = split(/\,/); # 置換前後文字列を euc code に変換 &jcode'convert(*rep_bef, "euc"); &jcode'convert(*rep_aft, "euc"); # 置換処理 $_[0] =~ s/$sign$rep_bef/$rep_aft/g; } close(DIC); # $conv_flag が 1(投稿コメントの文字コード変換を行っている)ならば # 投稿コメントを元のコードに変換 if ($conv_flag) { &jcode'convert(\$_[0], $code, "euc"); } return $_[0]; }