#!/usr/local/bin/perl #┌───────────────────────────────── #│ Message Enquete v1.7 (2002/09/09) #│ Copyright(C) Kent Web 2002 #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── $ver = 'Message Enquete v1.7'; #┌───────────────────────────────── #│ [ 注意事項 ] #│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した #│ いかなる損害に対して作者は一切の責任を負いません。 #│ 2. 設置に関する質問はサポートコーナにお願いいたします。直接 #│ メールによる質問は受け付けておりません。 #└───────────────────────────────── # # [ 設置例 ] # # public_html / index.html (トップページなど) # | # +-- msgenq / msgenq.cgi [755] # | msgenq.log [666] # | msgenq.dat [666] # | jcode.pl [644] # | graph.gif # | # +-- lock [777] / # # # [ チェックモードの仕方 ] : mode=check という引数を付けて呼出す # # 例 http://〜〜/msgenq.cgi?mode=check #============# # 設定 # #============# # jcode.pl取り込み require './jcode.pl'; # タイトル名 $title = "アンケート投票第一弾"; # タイトル文字の色 $t_color = "#008080"; # タイトル文字の大きさ (スタイルシートで反映) $t_size = '24px'; # 本文の文字大きさ (スタイルシートで反映) $b_size = '13px'; # 本文の文字タイプ (スタイルシートで反映) $f_family = "MS UI Gothic"; # スクリプト名 $script = './msgenq.cgi'; # ログファイル $logfile = './msgenq.log'; # メッセージログファイル $msgfile = './msgenq.dat'; # 投稿メッセージファイル最大保持数 $max = 100; # 初期画面で表示する上位項目数 # → 0 にすると最初から全項目を表示します $topview = 10; # 1ページ当りの記事表示数 $pageview = 20; # 投稿メッセージの文字数制限(全角換算で指定) $msg_max = 100; # 投稿メッセージの改行は有効にする (0=no 1=yes) $msg_br = 1; # 管理用パスワード $pass = 'george'; # ユーザ項目追加機能 (0=no 1=yes) # → yes だとユーザが自由に項目を追加することが可能となります $FreeItem = 1; # IPアドレスの保持件数(二重投稿禁止) # → これを 0 にすると二重投稿のチェックを行ないません $ipmax = 5; # グラフ画像 (絶対パスだと http://から) $graph = "./graph.gif"; # 戻り先 (絶対パスだと http://から) $home = "http://www.dcseikatsu.com/"; # bodyタグ $body = ''; # 記事の更新は「method=POST」限定 (セキュリティ強化) # 0 : 行なわない # 1 : 行なう $postonly = 1; # ロックファイル機構 # 0 : 行なわない # 1 : 行なう(symlink関数) # 2 : 行なう(mkdir関数) $lockkey = 0; # ロックファイル名 $lockfile = './lock/msgenq.lock'; # サブタイトル # --> タイトル下にサブタイトルを記述します(タグ使用可) $subtitle = <<'EOM';
  • あなたがアメリカに来た理由は何ですか?
  • コメントがありましたらいっしょにお聞かせください。
EOM # タイトル画像を使う場合 (http://から画像を指定) $ImgT = ""; # タイトル画像を使う場合に「横幅」「縦幅」をそれぞれピクセル数で記述 $ImgW = 300; $ImgH = 70; # タグ広告挿入オプション # → の代わりに「広告タグ」を挿入する。 # → 広告タグ以外に、MIDIタグ や LimeCounter等のタグにも使用可能。 $banner1 = ''; # 上部に挿入 $banner2 = ''; # 下部に挿入 # アクセス制限(半角スペースで区切る) # → 拒否するホスト名又はIPアドレスを記述(アスタリスク可) # → 記述例 $deny = '*.anonymizer.com *.denyhost.xx.jp 211.154.120.*'; $deny = ''; #============# # 設定完了 # #============# # メイン処理 &decode; &axs_check; if ($mode eq 'regist') { ®ist; } elsif ($mode eq 'admin') { &admin; } elsif ($mode eq 'MakeItem' && $FreeItem) { &MakeItem('USER'); } elsif ($mode eq 'check') { ✓ } &html; #----------------# # アクセス制限 # #----------------# sub axs_check { # ホスト名を取得 &get_host; local($flag)=0; foreach (split(/\s+/, $deny)) { next if (!$_); s/\*/\.\*/g; if ($host =~ /$_/i) { $flag=1; last; } } &error("アクセスを許可されていません") if ($flag); } #------------------# # 初期画面を表示 # #------------------# sub html { &header; print "[トップに戻る]\n"; print "
\n"; print "$banner1

\n" if ($banner1 ne ""); # タイトル if ($ImgT) { print "\"$title\"\n"; } else { print "


\n"; print "$title\n"; print "
\n"; } print "

コミュニティ
特集コラム
人々@D.C.生活
日本語ニュースサイト
ニュース一般
動画ニュース
芸能・エンターテイメント
IT & テクノロジー
スポーツ
便利サイト
翻訳
専門用語辞典
地図・ディレクション
D.C.生活.com
広告掲載について
格安ウエブデザイン
お問い合わせ

D.C.近郊で活動している個人、 お店、企業、グループの 皆様で当サイト上で紹介記事 を掲載希望の方はinfo@dcseikatsu.com までお気軽にご連絡下さい!
掲載料は無料です。


\n$subtitle\n
\n"; $total=0; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { ($no,$item,$count) = split(/<>/); $num{$no} = $no; $itm{$no} = $item; $cnt{$no} = $count; $total += $count; } close(IN); $all = &filler($total); print "
\n"; print "\n"; print "\n"; print "有効回答:$all件\n"; print "

\n"; print "\n"; # ソート処理 $rank1 = 0; $rank2 = 1; $temp = 0; @no=(); foreach (sort { ($cnt{$b} <=> $cnt{$a}) } keys(%cnt)) { push(@no,$num{$_}); ($cnt{$_} == $temp) || ($rank1 = $rank2); # トップ順位表示 if ($topview && $in{'view'} ne "all" && $topview < $rank1) { next; } if ($cnt{$_}) { $per = int(($cnt{$_}*1000 / $total)+0.5) / 10; $per = sprintf("%.1f", $per); $width = int($per * 3); if ($width < 1) { $width = 1; } $cnt = &filler($cnt{$_}); } else { $per = 0; $width = 1; $cnt = 0; } print ""; print ""; print "\n"; $temp = $cnt{$_}; $rank2++; } print "
順位項目得票数割合
$rank1$itm{$_}$cnt $per\%
\n"; # 回答フォーム print "

"; if ($topview) { @s = ("上位 $topview件", '全件表示'); print "\n"; } print "\n"; print "
表\示形態   "; if ($in{'view'} eq "all") { print "[$s[0]]   [$s[1]]\n"; } else { print "[$s[0]]   [$s[1]]\n"; } print "
項目選択  
コメント (全角$msg_max文字以内)
\n"; print "
\n

\n"; # 項目追加 if ($FreeItem) { print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "投票する項目が上記にない場合は以下のフォームから追加して下さい

\n"; print "\n"; print "

\n"; } # ページ区切り処理 $start = $page + 1; $end = $page + $pageview; # コメントを表示 print "\n
コメント一覧\n"; $i=0; open(IN,"$msgfile") || &error("Open Error : $msgfile"); while () { $i++; if ($i < $start) { next; } if ($i > $end) { last; } ($date,$item,$comment) = split(/<>/); print "

$item - $date\n"; print "
$comment\n"; } close(IN); print "

\n"; # ページ繰りボタン $next = $page + $pageview; $back = $page - $pageview; print "\n"; if ($back >= 0) { print "\n"; } if ($next < $i) { print "\n"; } # 管理用フォーム print <<"EOM";
\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
$banner2

- Message Enquete -
EOM exit; } #----------------# # 投票受付処理 # #----------------# sub regist { # POST限定 if ($postonly && !$post_flag) { &error("不正なアクセスです"); } if ($in{'item'} eq "") { &error("項目の選択がありません"); } if (length($in{'comment'}) > $msg_max*2) { &error("コメント文が長すぎます。全角$msg_max文字以内で記述して下さい"); } # ロック処理 if ($lockkey) { &lock; } @new=(); open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { chop; local($no,$item,$count,$host) = split(/<>/); if ($in{'item'} == $no) { $AnsItem = $item; $count++; $_="$no<>$item<>$count<>$host<>"; } push(@new,"$_\n"); } close(IN); if ($ipmax) { $top =~ s/\n//; @ip = split(/\s+/, $top); $match=0; $ip=""; $i=0; foreach (@ip) { $i++; if ($addr eq "$_") { $match=1; last; } if ($i < $ipmax) { $ip .= "$_ "; } } if ($match) { &error("連続投票はできません"); } $ip = "$addr $ip\n"; } else { $ip = "\n"; } # 更新 unshift(@new,$ip); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # コメント文記録 if ($in{'comment'}) { # 記事読込 open(IN,"$msgfile") || &error("Open Error : $logfile"); @lines = ; close(IN); # 更新 while ($max <= @lines) { pop(@lines); } &get_time; unshift(@lines,"$date<>$AnsItem<>$in{'comment'}<>$host<>\n"); open(OUT,">$msgfile") || &error("Write Error : $logfile"); print OUT @lines; close(OUT); } # ロック解除 if ($lockkey) { &unlock; } # 完了メッセージ &header; print <<"EOM";


ご回答ありがとうございました


EOM exit; } #--------------# # 管理モード # #--------------# sub admin { if ($in{'pass'} ne $pass) { &error("パスワードが違います"); } # 項目追加処理 if ($in{'item'} && !$in{'ope'}) { &MakeItem; } # 修正フォーム elsif ($in{'ope'} eq 'mente' && $in{'no'}) { open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; @new = ($top); while () { ($no,$item,$count,$host) = split(/<>/); last if ($in{'no'} == $no); } close(IN); &header; print "

項目修正フォーム

\n"; print "- 修正する項目のみ変更して送信ボタンを押して下さい
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "項目名
\n"; print "投票数
\n"; print "
\n"; print "\n\n"; exit; } # 修正実行 elsif ($in{'ope'} eq 'mente2' && $in{'no'}) { # 入力チェック if ($in{'item'} eq '') { &error('項目名に入力がありません'); } if ($in{'count'} =~ /\D/) { &error('投票数に半角数字以外の文字が入力されています'); } # ロック開始 &lock if ($lockkey); open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; @new = ($top); while () { ($no,$item,$count,$host) = split(/<>/); if ($in{'no'} == $no) { $_ = "$no<>$in{'item'}<>$in{'count'}<>$host<>\n"; } push(@new,$_); } close(IN); # 更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # ロック解除 &unlock if ($lockkey); } # 削除処理 elsif ($in{'ope'} eq 'del' && $in{'no'}) { # ロック開始 &lock if ($lockkey); open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; @new = ($top); while () { ($no) = split(/<>/); next if ($in{'no'} == $no); push(@new,$_); } close(IN); # 更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); # ロック解除 &unlock if ($lockkey); } &header; print <<"EOM"; [戻る]

管理モード


1. 項目の追加
項目

2. 項目の修正・削除

EOM open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while () { chop; ($no,$item,$count,$host) = split(/<>/); if (!$host) { $host = '
'; }; print "
"; print "\n"; } close(IN); print "
選択項目得票数ホスト
$item$count$host

\n"; # ロック開始 if ($in{'action'} eq "mesg_del" && $lockkey) { &lock; } open(IN,"$msgfile") || &error("Open Error : $msgfile"); @lines = ; close(IN); # 削除処理 if ($in{'action'} eq "mesg_del") { if ($in{'del'} eq "") { &error("削除項目がありません"); } @DEL = split(/\0/, $in{'del'}); @new=(); foreach (@lines) { $flag=0; ($date) = split(/<>/); foreach $i (@DEL) { if ($i eq $date) { $flag=1; last; } } if ($flag == 0) { push(@new,$_); } } # 更新 open(OUT,">$msgfile") || &error("Write Error : $msgfile"); print OUT @new; close(OUT); # ロック解除 if ($lockkey) { &unlock; } @lines = @new; } print "
3. コメントの削除\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; foreach (@lines) { ($date,$item,$com,$host) = split(/<>/); print "
"; print "$item - $date ($host)\n"; print "
$com\n"; } print "
\n"; print "
\n"; print "\n\n"; exit; } #------------------# # ユーザ項目追加 # #------------------# sub MakeItem { # POST限定 if ($_[0] eq 'USER' && $postonly && !$post_flag) { &error("不正なアクセスです"); } $item =~ s/\s//g; if ($item eq '') { &error("追加する項目名がありません"); } # ロック処理 if ($lockkey) { &lock; } $flag=0; open(IN,"$logfile") || &error("Open Error : $logfile"); $top = ; while() { ($no,$item2) = split(/<>/); if ($item eq $item2) { $flag=1; last; } } close(IN); if ($flag) { &error("この項目は既に存在するため追加できません"); } $no++; open(OUT,">>$logfile") || &error("Write Error : $logfile"); print OUT "$no<>$item<>0<>$host<>\n"; close(OUT); # ロック解除 if ($lockkey) { &unlock; } } #----------------# # デコード処理 # #----------------# sub decode { local($buf, $key, $val, @buf); $post_flag=0; if ($ENV{'REQUEST_METHOD'} eq "POST") { $post_flag=1; read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } @buf = split(/&/, $buf); foreach (@buf) { ($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # シフトJIS変換 &jcode'convert(*val, "sjis", "", "z"); # タグ禁止 $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s//>/g; # 改行コード if ($msg_br && $key eq "comment") { $val =~ s/\r\n/
/g; $val =~ s/\r/
/g; $val =~ s/\n/
/g; } else { $val =~ s/\r//g; $val =~ s/\n//g; } $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } $mode = $in{'mode'}; $page = $in{'page'}; $item = $in{'item'}; } #--------------# # HTMLヘッダ # #--------------# sub header { $headflag = 1; print "Content-type: text/html\n\n"; print <<"EOM"; $title $body EOM } #--------------# # エラー処理 # #--------------# sub error { &unlock if ($lockflag); &header if (!$headflag); print "

ERROR !

\n"; print "$_[0]
\n"; print "\n\n"; exit; } #--------------# # ロック処理 # #--------------# sub lock { # 1分以上古いロックは削除する if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { &unlock; } } local($retry) = 5; # symlink関数式ロック if ($lockkey == 1) { while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } # mkdir関数式ロック } elsif ($lockkey == 2) { 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 filler { local($_) = $_[0]; 1 while s/(.*\d)(\d\d\d)/$1,$2/; return $_; } #----------------# # ホスト名取得 # #----------------# 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 get_time { # 日時の取得 $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:%02d", $year+1900,$mon+1,$mday,$week[$wday],$hour,$min,$sec); } #------------------# # チェックモード # #------------------# sub check { &header; print "

Check Mode

\n"; print "
    \n"; # 項目ファイル if (-e $logfile) { print "
  • ログファイルのパス:OK\n"; # パーミッション if (-r $logfile && -w $logfile) { print "
  • ログファイルのパーミッション:OK\n"; } else { print "
  • ログファイルのパーミッション:NG\n"; } } else { print "
  • ログファイルのパス:NG → $logfile\n"; } # メッセージファイル if (-e $msgfile) { print "
  • メッセージファイルのパス:OK\n"; # パーミッション if (-r $msgfile && -w $msgfile) { print "
  • メッセージファイルのパーミッション:OK\n"; } else { print "
  • メッセージファイルのパーミッション:NG\n"; } } else { print "
  • メッセージファイルのパス:NG → $msgfile\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"; if (-r $lockdir && -w $lockdir && -x $lockdir) { print "
  • ロックディレクトリのパーミッション:OK\n"; } else { print "
  • ロックディレクトリのパーミッション:NG → $lockdir\n"; } } else { print "
  • ロックディレクトリのパス:NG → $lockdir\n"; } } print "
\n\n\n"; exit; } __END__
Copyright ゥ 2006 DCSeikatsu.com. All rights reserved.