#!/usr/local/bin/perl # ### CGIカウンター SDcountH Ver.1.00 ### (イメージタグ埋め込み型) ### ### Copyright (c) 2001 Sentora Dori ### http://lowpower.iis.u-tokyo.ac.jp/~hat # #################### 変数設定 #################### # カウンタファイルをおくディレクトリのパス $basedir = "."; #################### 変数設定(ここまで) #################### # 2: flockを使用する 1: ロックファイルでロックする 0: ロックしない (通常は変更必要なし) $uselock = 2; # flockを使用しないロックのときのロックファイル名のベース (変更必要なし) $baselockfile = './SDlock'; ### data format ### require './gifcat.pl'; &init_form(); $countfile = "$basedir/$countname.txt"; ### get host ### $hostaddr = $ENV{'REMOTE_ADDR'}; $hostname = $ENV{'REMOTE_HOST'}; if ($hostaddr eq $hostname || $hostname eq '') { $hostname = gethostbyaddr(pack("C4", split(/\./, $hostaddr)), 2); } ### data file open ### if (!open(OUT, "+<$countfile")) { &print_error('[no counter data]'); } # file lock if (!&lock_file(OUT)) { &print_error('[lock error]'); } # image file check if (!(-f "$gifdir/0.gif")){ &print_error("[no image files]"); } ### get counter ### seek(OUT, 0, 0); $totalcount = 1 + ; $yesterdaycount = 0 + ; $todaycount = 1 + ; $lastday = ; $lasthost = ; chomp($lasthost); ### reload? ### if (($ban_reload || !$countup) && $hostaddr eq $lasthost) { $totalcount--; $todaycount--; &unlock_file(OUT); close(OUT); if ($usecookie) { $nochange = 1; $yourcount--; } goto SHOWPAGE; } ### get time ### ($sec, $min, $hour, $day, $mon, $year) = localtime(time); $mon++; $year += 1900; $today = "$year-$mon-$day\n"; ### first access today? ### if ($today ne $lastday) { ($sec2, $min2, $hour2, $day2, $mon2, $year2) = localtime(time - 24*60*60); $mon2++; $year2 += 1900; $yesterday ="$year2-$mon2-$day2\n"; if ($yesterday ne $lastday) { $yesterdaycount = 0; } else { $yesterdaycount = $todaycount - 1; } $todaycount =1; $lastday = $today; } ### put counter ### seek(OUT, 0, 0); print OUT "$totalcount\n"; print OUT "$yesterdaycount\n"; print OUT "$todaycount\n"; print OUT "$lastday"; print OUT "$hostaddr\n"; &unlock_file(OUT); close(OUT); ### html header ### SHOWPAGE: print "Content-type: image/gif\n"; print "\n"; ### showcounter ### $count = $totalcount; $count = $yesterdaycount if ($type eq 'yesterday'); $count = $todaycount if ($type eq 'today'); $count = $yourcount if ($type eq 'your'); &show_counter($count); ### end ### exit(0); ################## ### subroutine ### ################## #----- ブラウザへ出力 ----- sub show_counter { local($count) = @_; @num = split(//, $count); if ($counter_order) { while (@num < $counter_order) { unshift(@num, "0"); } } for(0..$#num){ $num[$_]="$gifdir/$num[$_].gif"; } binmode(STDOUT); $| = 1; print &gifcat'gifcat(@num); } #----- ブラウザへの入力データの取得 ----- sub init_form { local($query, @param, $method); $method = $ENV{'REQUEST_METHOD'}; $method =~ tr/A-Z/a-z/; if ($method eq 'post') { read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } else { $query = $ENV{'QUERY_STRING'}; } @param = split(/&/, $query); $countname = ($param[0] =~ /^\w+$/) ? $param[0] : ''; $countup = ($param[1] == 1) ? $param[1] : 0; $type = ($param[2] =~ /^\w+$/) ? $param[2] : 'total'; $counter_order = ($param[3] =~ /^\d+$/) ? $param[3] : 5; $gifdir = ($param[4]) ? $param[4] : './img/default'; $ban_reload = ($param[5] == 1) ? $param[5] : 0; } #----- ファイルロック ----- sub lock_file { local($FILE) = @_; local($LOCK) = "LOCK$FILE"; local($lockfile) = "$baselockfile$FILE"; local($retry) = 10; if ($uselock == 2) { eval(flock($FILE, 2)); if ($@) { return 0; } else { return 1; } } elsif ($uselock == 1) { while (-f $lockfile) { sleep(0.3); return 0 if (--$retry <= 0); } open($LOCK, ">$lockfile") || return 0; close($LOCK); return 1; } else { return 1; } } #----- ファイルアンロック ----- sub unlock_file { local($FILE) = @_; local($lockfile) = "$baselockfile$FILE"; if ($uselock == 2) { flock($FILE, 8); } elsif ($uselock == 1) { unlink($lockfile); } } ##### エラー処理 ##### #----- エラー文を出力し終了 ----- sub print_error { local($msg) = @_; print "Content-type: text/plain\n\n"; print $msg; exit(0); }