#!/bin/sh # # hitcheck.cgi # WARNING: Please DO NOT use this unless you know what you are doing. # Althought it's relatively light, it may require lots of CPU power # if the log is huge. Put into a protected directory. # # It will check the 25000 th line from the end of access_log # and determine if one hour has passed since that entry was made. # # In other words, it only checks if the hit count was more than # certain threshold or not. # # I tried to make it as light as possible to check it every half an hour or so # without using lots of server resources, so that you can trigger # defensive actions (if you can think of something .....) # # Optionally, you can specify the number of lines other than 25000 # http://yourdomain.com/protected/hitcheck.cgi?5000 # or # http://yourdomain.com/protected/hitcheck.cgi?l=5000 # The maximum is 32500 and minimum is 1. # echo -e "Content-type: text/html\n\n" main(){ # Edit tags as you like. echo "
"

U=`id -u`
U=$(($U-500))
LOG="/log/access/${U%${U#?}}/${U}_access_log"
NOW='NOW=$(( '`date "+ %H * 60 + %M "`'))'
eval "$NOW"
case "$1" in ));; '')NUM="${QUERY_STRING#l=}";;*)NUM="$1";;esac

case "$NUM" in ));; 
 *[!0-9]*)echo "Error #1 '$NUM' contains non-digit (must be an integer)";exit;;
 ??????*) echo "Error #2 '$NUM' too big (Max 32500)";exit;;
  [0-9])echo "Error #4 '$NUM' too small (Min 10)";exit;;
esac

XX=${NUM:=25000}
XX=$((32500-$NUM))
case $XX in
  -*)echo "Error #3 '$NUM' too big (Max 32500)";exit;;
esac
echo "Checking $NUM th line from the end."
LINE=`tail -$NUM $LOG 2>/dev/null |head -1`
#echo "$LINE"

H=${LINE#*:}
M=${H#*:}
H=${H%%:*}
M=${M%%:*}
HM=$(($H*60 + $M))
#echo "H=$H , M=$M , HM=$HM"
DIF=$(($NOW - $HM -60))
#echo "DIF=$DIF"

case $DIF in
  -*)echo "Over $NUM hits for the last hour"
  # Do something here to reduce hits .... if you can do something at all ...
    return 1
  ;; 
  *)echo "Under $NUM hits for the last hour"
  ;;
esac

}

main 2>&1

# end