#┌───────────────────────────────── #│ Web Patio v3.06 #│ init.cgi - 2006/11/11 #│ Copyright (c) KentWeb #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── $ver = 'WebPatio v3.06'; #┌───────────────────────────────── #│ [注意事項] #│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した #│ いかなる損害に対して作者は一切の責任を負いません。 #│ 2. 設置に関する質問はサポート掲示板にお願いいたします。 #│ 直接メールによる質問は一切お受けいたしておりません。 #│ 3. 添付画像のうち、以下のファイルを再配布しています。 #│ ・牛飼いとアイコンの部屋 (http://www.ushikai.com/) #│ alarm.gif book.gif fold4.gif glass.gif memo1.gif memo2.gif #│ pen.gif trash.gif mente.gif #└───────────────────────────────── # # 【ファイル構成例】 # # public_html (ホームディレクトリ) # | # +-- patio / # | patio.cgi [705] # | regist.cgi [705] # | admin.cgi [705] # | init.cgi [604] # | note.html # | # +-- data / index1.log [606] # | index2.log [606] # | memdata.cgi [606] # | # +-- lib / jcode.pl [604] # | upload.pl [604] # | edit_log.pl [604] # | find.pl [604] # | check.pl [604] # | # +-- log [707] / # | # +-- ses [707] / # | # +-- upl [707] / # | # +-- img / *.gif #------------------------------------------------- # ◎基本設定 #------------------------------------------------- # 外部ファイル $jcode = './lib/jcode.pl'; $upload = './lib/upload.pl'; $editlog = './lib/edit_log.pl'; $findpl = './lib/find.pl'; $checkpl = './lib/check.pl'; # 管理パスワード(英数字で8文字以内) $pass = 'tokyo'; # アクセス制限をする # 0=no 1=yes $authkey = 0; # ログイン有効期間(分) $authtime = 60; # トリップ機能(ハンドル偽造防止)のための変換キー # → 英数字で2文字 $trip_key = 'ab'; # タイトル $title = "★★求人・求職情報交換★★"; # タイトルの文字色 $t_color = "#ff00aa"; # タイトルサイズ $t_size = '20px'; # 本文文字サイズ $b_size = '16px'; # 本文文字フォント $b_face = '"MS UI Gothic", Osaka, "MS Pゴシック"'; # 掲示板本体CGI【URLパス】 $bbscgi = './patio.cgi'; # 掲示板投稿CGI【URLパス】 $registcgi = './regist.cgi'; # 掲示板閲覧CGI【URLパス】 $readcgi = './todos.cgi'; # 掲示板管理CGI【URLパス】 $admincgi = './admin.cgi'; # 留意事項ページ【URLパス】 $notepage = './note.html'; # 現行ログindex【サーバパス】 $nowfile = './data/index1.log'; # 過去ログindex【サーバパス】 $pastfile = './data/index2.log'; # 会員ファイル【サーバパス】 $memfile = './data/memdata.cgi'; # 記録ファイルディレクトリ【サーバパス】 $logdir = './log'; # セッションディレクトリ【サーバパス】 $sesdir = './ses'; # 戻り先【URLパス】 $home = '../check/check.cgi'; # 壁紙 $bg = ""; # 背景色 $bc = "#F0F0F0"; # 文字色 $tx = "#000000"; # リンク色 $lk = "#0000FF"; $vl = "#800080"; $al = "#DD0000"; # 返信記事にも画像をアップする (0=no 1=yes) $resup = 1; # 画像ディレクトリ【URLパス】 $imgurl = './img'; # アクセス制限(半角スペースで区切る) # → 拒否するホスト名又はIPアドレスを記述(アスタリスク可) # → 記述例 $deny = '*.anonymizer.com 211.154.120.*'; $deny = ''; # 記事の更新は method=POST 限定 (0=no 1=yes) # (セキュリティ対策) $postonly = 1; # 連続投稿の禁止時間(秒) $wait = 60; # 禁止ワード # → 投稿時禁止するワードをコンマで区切る $no_wd = ''; # 日本語チェック(投稿時日本語が含まれていなければ拒否する) # 0=No 1=Yes $jp_wd = 1; # URL個数チェック # → 投稿コメント中に含まれるURL個数の最大値 $urlnum = 5; # 名前入力必須 (0=no 1=yes) $in_name = 1; # E-Mail入力必須 (0=no 1=yes) $in_mail = 0; # 削除キー入力必須 (0=no 1=yes) $in_pwd = 1; # 現行ログ最大スレッド数 # → これを超えると過去ログへ移動 $i_max = 100; # 過去ログ最大スレッド数 # → これを超えると自動削除 $p_max = 1000; # 1スレッド当りの「表示」記事数 $t_max = 5; # 1スレッド当りの「最大」記事数 # → これを超えると過去ログへ廻ります # → 残り90%でアラームを表示します $m_max = 500; # 現行ログ初期メニューのスレッド表示数 $menu1 = 20; # 過去ログ初期メニューのスレッド表示数 $menu2 = 20; # 色指定(順に、濃色、薄色、中間色) $col1 = "#8080C0"; $col2 = "#FFFFFF"; $col3 = "#DCDCED"; # 繰越ページ数の当該ページの色 $pglog_col = "#DD0000"; # コメント入力文字数(全角換算) $max_msg = 2000; # スマイルアイコンの使用 (0=no 1=yes) $smile = 1; # スマイルアイコンの定義 (スペースで区切る) # → ただし、この設定箇所は変更しないほうが無難 # → 顔文字に半角カナや2バイト文字は使用厳禁(正規表現上の制約) $smile1 = 'smile01.gif smile02.gif smile03.gif smile04.gif smile05.gif smile06.gif smile07.gif'; $smile2 = '(^^) (^_^) (+_+) (^o^) (^^;) (^_-) (;_;)'; # メール送信 # 0 : しない # 1 : スレッド生成時 # 2 : 投稿記事すべて $mailing = 0; # メール送信先 $mailto = 'todosml@todos.xsrv.jp'; # sendmailパス $sendmail = '/usr/sbin/sendmail'; # ホスト取得方法 # 0 : gethostbyaddr関数を使わない # 1 : gethostbyaddr関数を使う $gethostbyaddr = 0; # アクセス制限(半角スペースで区切る、アスタリスク可) # → 拒否ホスト名を記述(後方一致)【例】*.anonymizer.com $deny_host = ''; # → 拒否IPアドレスを記述(前方一致)【例】210.12.345.* $deny_addr = ''; # 1回当りの最大投稿サイズ (bytes) $maxData = 51200; # 画像ディレクトリ # → 順に、サーバパス、URLパス $upldir = './upl'; $uplurl = './upl'; # アップ画像の最大表示の大きさ(単位:ピクセル) # → これを超える画像は縮小表示します $img_max_w = 275; # 横幅 $img_max_h = 275; # 縦幅 # NEWマークの表示形態# $newmark = ''; $newmark = 'new!'; # 記事にNEWマークを付ける時間 $newmark_time = 72; #------------------------------------------------- # ◎設定完了 #------------------------------------------------- # 画像拡張子 %imgex = (".jpg",1,".gif",1,".png",1); #------------------------------------------------- # アクセス制限 #------------------------------------------------- sub axscheck { # 時間取得 ($time, $date) = &get_time; # IP&ホスト取得 $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($gethostbyaddr && ($host eq "" || $host eq $addr)) { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2); } # IPチェック local($flg); foreach ( split(/\s+/, $deny_addr) ) { s/\./\\\./g; s/\*/\.\*/g; if ($addr =~ /^$_/i) { $flg = 1; last; } } if ($flg) { &error("アクセスを許可されていません"); # ホストチェック } elsif ($host) { foreach ( split(/\s+/, $deny_host) ) { s/\./\\\./g; s/\*/\.\*/g; if ($host =~ /$_$/i) { $flg = 1; last; } } if ($flg) { &error("アクセスを許可されていません"); } } if ($host eq "") { $host = $addr; } # 会員制限 if ($authkey) { # 時間 local($time) = time; # ログイン if ($mode eq "login") { # 会員ファイル local($flg); open(IN,"$memfile") || &error("Open Error: $memfile"); while () { ($id,$pw,$rank,$nam) = split(/<>/); if ($in{'id'} eq $id) { $flg = 1; if (&decrypt($in{'pw'},$pw) == 1) { $flg = 2; $data = "$rank<>$nam"; $my_name = $nam; $my_rank = $rank; } last; } } close(IN); if ($flg < 2) { &error("認証できません"); } # セッションID発行 @char = (0 .. 9, 'a' .. 'z', 'A' .. 'Z'); $cookid; srand; foreach (1 .. 10) { $cookid .= $char[int(rand(@char))]; } # セッションID発行 open(OUT,">$sesdir/$cookid.cgi"); print OUT "$in{'id'}<>$time<>$data"; close(OUT); # セッションクッキー埋め込み print "Set-Cookie: patio_member=$cookid;\n"; # クッキーID&ログインID $my_ckid = $cookid; $my_id = $in{'id'}; # ログイン中 } else { local($cook,$sesdata,%cook); # クッキー取得 $cook = $ENV{'HTTP_COOKIE'}; # 該当IDを取り出す foreach ( split(/;/, $cook) ) { local($key,$val) = split(/=/); $key =~ s/\s//g; $cook{$key} = $val; } if (!$cook{'patio_member'} || ! -e "$sesdir/$cook{'patio_member'}.cgi") { &enter_disp; } # センションファイル open(IN,"$sesdir/$cook{'patio_member'}.cgi"); $sesdata = ; close(IN); local($id,$tim,$rank,$nam) = split(/<>/, $sesdata); # 時間チェック if ($time - $tim > $authtime*60) { unlink("$sesdir/$cook{'patio_member'}.cgi"); print "Set-Cookie: patio_member=;\n"; &error("ログイン有効時間を経過しました。再度ログインしてください。
【再ログイン】"); } # 名前&クッキーID&ログインID $my_name = $nam; $my_ckid = $cook{'patio_member'}; $my_id = $id; $my_rank = $rank; } } } #------------------------------------------------- # フォームデコード #------------------------------------------------- sub parse_form { undef(%in); undef(%fname); undef(%uplno); undef(%ctype); $macbin = 0; $postflag = 0; # マルチパートフォームのとき if ($ENV{'CONTENT_TYPE'} =~ m|multipart/form-data|) { $postflag = 1; # 変数初期化 local($bound,$key,$val); # 標準入力をバイナリモード宣言 binmode(STDIN); # 先頭のboundaryを認識 $bound = ; $bound =~ s/\r\n//; # 標準入力を展開 while () { # マックバイナリ認識 if (m|application/x-macbinary|i) { $macbin = 1; } # Content-Disposition認識 if (/^Content-Disposition:/i) { $flg = 1; } # name属性認識 if ($flg == 1 && /\s+name="([^";]+)"/i) { $key = $1; if ($key =~ /^upfile(1|2|3)$/) { $uplno = $1; $uplno{$uplno} = $uplno; } } # filename属性認識(ファイルアップ) if ($uplno && /\s+filename="([^";]+)"/i) { $fname{$uplno} = $1; } # Content-Type認識(ファイルアップ) if ($uplno && /Content-Type:\s*([^";]+)/i) { local($ctype) = $1; $ctype =~ s/\r//g; $ctype =~ s/\n//g; $ctype{$uplno} = $ctype; } # ヘッダ → 本文 if ($flg == 1 && /^\r\n/) { $flg = 2; next; } # 本文認識 if ($flg == 2) { # boundary検出 → フィールド終了 if (/^$bound/) { # 末尾の改行をカット $val =~ s/\r\n$//; # テキスト系は改行を変換 if (!$uplno) { # S-JISコード変換 &jcode'convert(*val, 'sjis'); # エスケープ $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s//>/g; $val =~ s/\r\n/
/g; $val =~ s/\r/
/g; $val =~ s/\n/
/g; } # ハッシュ化 $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; # フラグを初期化 $flg = $uplno = $key = $val = ''; next; } # boundary検出まで本文を覚えておく $val .= $_; } } # マルチパートフォーム以外のとき } else { local($buf); if ($ENV{'REQUEST_METHOD'} eq "POST") { $postflag = 1; read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } foreach ( split(/&/, $buf) ) { local($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; # S-JISコード変換 &jcode'convert(*val, 'sjis'); # エスケープ $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s//>/g; $val =~ s/\r\n/
/g; $val =~ s/\r/
/g; $val =~ s/\n/
/g; # ハッシュ化 $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } } $mode = $in{'mode'}; $date_check = (&get_time('newmark'))[1]; $p = $in{'p'}; $i_nam = $in{'name'}; $i_sub = $in{'sub'}; $i_com = $in{'comment'}; $headflag = 0; } #------------------------------------------------- # HTMLヘッダ #------------------------------------------------- sub header { local($sub, $js) = @_; if ($sub ne '') { $title = $sub; } print "Content-type: text/html\n\n"; print <<"EOM"; EOM # JavaScript if ($js eq "js") { print "\n"; print "$title\n"; # bodyタグ if ($bg) { print "\n"; } else { print "\n"; } $headflag = 1; } #------------------------------------------------- # エラー処理 #------------------------------------------------- sub error { &header if (!$headflag); print <<"EOM";

ERROR !

$_[0]

EOM exit; } #------------------------------------------------- # 時間取得 #------------------------------------------------- sub get_time { $ENV{'TZ'} = "JST-9"; local($time) = time; if ($_[0] eq 'newmark') { $time = $time - $newmark_time*60*60; } local($min,$hour,$mday,$mon,$year) = (localtime($time))[1..5]; # 日時のフォーマット local($date) = sprintf("%04d/%02d/%02d %02d:%02d", $year+1900,$mon+1,$mday,$hour,$min); return ($time, $date); } #------------------------------------------------- # 入室画面 #------------------------------------------------- sub enter_disp { &header; print <
・ 入室にはログインIDとパスワードが必要です。
・ ブラウザのクッキーは必ず有効にしてください。

ログインID
パスワード

EOM exit; } #------------------------------------------------- # crypt暗号 #------------------------------------------------- sub encrypt { local($inpw) = @_; local($salt, $encrypt, @char); # 文字列定義 @char = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); # 乱数で種を生成 srand; $salt = $char[int(rand(@char))] . $char[int(rand(@char))]; # 暗号化 $encrypt = crypt($inpw, $salt) || crypt ($inpw, '$1$' . $salt); $encrypt; } #------------------------------------------------- # crypt照合 #------------------------------------------------- sub decrypt { local($inpw, $enpw) = @_; if ($enpw eq "") { &error("認証できません"); } # 種抜き出し local($salt) = $enpw =~ /^\$1\$(.*)\$/ && $1 || substr($enpw, 0, 2); # 照合処理 if (crypt($inpw, $salt) eq $enpw || crypt($inpw, '$1$' . $salt) eq $enpw) { return (1); } else { return (0); } } 1;