#!/usr/bin/perl -w ################################################################################ # プログラム名: he.cgi - 「へぇ」カウントCGI # バージョン : 0.02 # 最終更新日 : 2006/02/05 # 作成者 : CK (デジモノに埋もれる日々 http://c-kom.homeip.net/review/blog/) # ################################################################################ # # ■ 呼び出し方 # # [カウント] … cgiをゲットで呼び出します。 # http://(ホスト名.ドメイン名)/cgi-bin/(heディレクトリ)/he.cgi?uid=(ユーザ識別子)&eid=(記事ID)&value=(へぇカウント数) # (例) http://foobar.hoge.jp/cgi-bin/he/he.cgi?uid=testblog&eid=518&value=10 # # [カウント数表示] … 対応する.jsをhtmlに貼り付けます。 # # (例) # # ■ 作成されるファイル # 記事の数だけ .cnt ファイル、.js ファイルが作られます。 # # .cnt …管理用ファイル。 # [内容] # EID: (記事ID) # COUNT: (へぇカウント数) # LASTIP: (最後にへぇをしたIPアドレス) # .js …表示用javascriptファイル # [内容] # document.write(' (へぇカウント数) '); # # # ■ ディレクトリ構成 # he.cgiは cgi実行可能ディレクトリ (/cgi-bin/など) の配下に置きます。その下に .cnt が保存されます。 # 表示のための .js の置場は、ネットから直接ファイル参照できる場所に置きます。 # # /cgi-bin/(heディレクトリ)/ … he.cgi本体を置く # +- (ユーザ識別子)/ … (記事ID).cnt が保存される # /html/((he.cgiディレクトリ))/ # +- (ユーザ識別子)/ … (記事ID).js が保存される # # (例) ディレクトリ構成 # /cgi-bin/he/ # +- blog1/ # +- blog2/ # : # /html/he/ # +- blog1/ # +- blog2/ # : # # ■ 先読みFAQ # Q. ユーザ識別子って何? 勝手な文字列ってこと? 無くてもいいんじゃ? # A. 複数のブログを持っている方のために、ブログごとにディレクトリ分けする方向で。 # # Q. 何で.cntと.jsって別々なの? 煩わしいから.cntの内容も.jsに埋め込んじゃえば? # A. LASTIPの情報だけは公開側に置けないので、こんなになってます…。 # ################################################################################ ## ユーザ設定値 $base_cgi_dir = "/var/hoge/cgi-bin/he/"; # he.cgi本体と.cntの置場 $base_html_dir = "/var/hoge/html/he/"; # .jsの置場 ################################################################################ ## ここからプログラム ### GET読み込み。POSTなし。 $get_data = $ENV{'QUERY_STRING'}; $ip = $ENV{'REMOTE_ADDR'}; $referer = $ENV{'HTTP_REFERER'}; ### GET解析。 if ( $get_data eq "" ) { &errmes(1); exit; } @pairs = split(/&/, $get_data); foreach $pair (@pairs) { ($key, $value) = split(/=/, $pair); $QUERY{"$key"} = $value; } ### エラー判定など。 if ( !(exists $QUERY{'uid'}) || !(exists $QUERY{'eid'}) || !(exists $QUERY{'value'}) ) { &errmes(1); # uid,eid,valueのパラメータが欠けていればエラー。 exit; } $uid = $QUERY{'uid'}; # ユーザ識別ID。 $eid = $QUERY{'eid'}; # 記事ID。 $value = $QUERY{'value'}; # へぇカウント数。 $cnt_dir = $base_cgi_dir.$uid."/"; # .cntファイルを置くディレクトリ。 $js_dir = $base_html_dir.$uid."/"; # .jsファイルを置くディレクトリ。 if ( !(-d $cnt_dir) || !(-d $js_dir) ) { &errmes(1); # ディレクトリが存在しない場合はエラー。 exit; } if ( $value =~ /\D/ ) { &errmes(1); # へぇカウント数に数字じゃない文字が混ざっていればエラー。 exit; } $cnt_filename = $cnt_dir.$eid.".cnt"; # .cntファイル名決定。 $js_filename = $js_dir.$eid.".js"; # .jsファイル名決定。 ## .cntファイルの読み込み。COUNT: カウント数、LASTIP: 最後にへぇがあったIPアドレス。 if ( -e $cnt_filename ) { open( CNT_FILE, "<", $cnt_filename ); flock( CNT_FILE, 2 ); while ( $line = ) { chop( $line ); ( $cnt_label, $cnt_value ) = split( /: /, $line ); if ( $cnt_label =~ /COUNT/ ) { $count = $cnt_value; } elsif ( $cnt_label =~ /LASTIP/ ) { $lastip = $cnt_value; } } close( CNT_FILE ); } else { $count = 0; $lastip = "0.0.0.0"; } ## 同一IPからの連続へぇだったらエラーを出して終了。 if ( $ip eq $lastip ) { &errmes(2); exit; } ## カウント数を増やす。IPも新しいものに更新。 $new_count = $count + $value; $new_lastip = $ip; ## .cntファイル更新。EID: 記事ID、COUNT: カウント数、LASTIP: 最後にへぇがあったIPアドレス。 open( CNT_FILE, ">", $cnt_filename ); flock( CNT_FILE, 2 ); print CNT_FILE "EID: " .$eid. "\n"; print CNT_FILE "COUNT: " .$new_count. "\n"; print CNT_FILE "LASTIP: " .$new_lastip. "\n"; close( CNT_FILE ); ## .jsファイル更新。カウント数を表示するだけ。ここでは数字の大小によって表示文字($js_string)の装飾を変えている。 open( JS_FILE, ">", $js_filename ); flock( JS_FILE, 2 ); if ( $new_count < 20 ) { $js_string = "" .$new_count. ""; } elsif ( $new_count < 40 ) { $js_string = "" .$new_count. ""; } elsif ( $new_count < 60 ) { $js_string = "" .$new_count. ""; } elsif ( $new_count < 80 ) { $js_string = "" .$new_count. ""; } elsif ( $new_count < 100 ) { $js_string = "" .$new_count. ""; } else { $js_string = "" .$new_count. ""; } print JS_FILE "document.write('" .$js_string. "');"; close( JS_FILE ); ## 正常終了 &errmes(0); ### 以下、サブルーチン。 ## 結果メッセージ表示( errcode=0: 正常、errcode=それ以外: エラー) sub errmes { my ( $errcode ) = @_; my $sec = 3; $print_header = ""; $print_header .= "Content-type: text/html\n\n"; $print_header .= "\n"; $print_header .= "\n"; $print_header .= "\n"; $print_header .= ""; $print_header .= "\n"; $print_header .= "\n"; $print_message = ""; if ( $errcode == 0 ) { # 正常 $print_message .= "『 " .$value. "へぇ 』 がカウントされました。ありがとうございました!

\n"; } elsif ( $errcode == 1 ) { # パラメータが足りない or 値が不正 $print_message .= "he.cgi : パラメータが正しくありませんでした。

\n"; } elsif ( $errcode == 2 ) { # 同一IPからの連続へぇを阻止 $print_message .= "he.cgi : 同一ホストからの「へぇ」は連続してカウントされません。

\n"; } $print_footer =""; $print_footer .= "元のページに戻らない場合は 戻る をクリックするか、
\n"; $print_footer .= "ブラウザの「戻る」ボタンをご使用ください。
\n"; $print_footer .= "\n"; $print_footer .= "\n"; print $print_header; print $print_message; print $print_footer; }