diff -urN tdiary-3.0.1.orig/misc/plugin/counter.rb tdiary-3.0.1/misc/plugin/counter.rb
--- tdiary-3.0.1.orig/misc/plugin/counter.rb	2010-09-20 15:33:51.000000000 +0900
+++ tdiary-3.0.1/misc/plugin/counter.rb	2010-09-23 23:25:56.000000000 +0900
@@ -175,6 +175,12 @@
 def counter_allow?
 	return false if bot?
 	if @options
+		if @options["spamfilter.bad_ip_addrs"]
+			@conf.options['spamfilter.bad_ip_addrs'].split(/[\r\n]+/).each do |ip|
+				next if ip.empty?
+				return false if @cgi.remote_addr.index(ip) == 0
+			end
+		end
 		if @options["counter.deny_user_agents"]
 			if @options["counter.deny_user_agents"].kind_of? Array
 				@options["counter.deny_user_agents"] = @options["counter.deny_user_agents"].uniq.join('|')
@@ -243,6 +249,7 @@
 			end
 			@all += 1
 			save
+			uplog(cgi)
 		end
 
 		def load
@@ -281,6 +288,17 @@
 				save("counter2.dat." + @newestday.wday.to_s)
 			end
 		end
+
+		def uplog(cgi)
+			begin
+				time = Time.now
+				open(File.join(@path, "counterup_" + time.strftime("%Y%m%d") + ".log"), "a") do |io|
+					io.print time, "\t", cgi.remote_addr, "\t", cgi.user_agent, "\n"
+				end
+			rescue
+				warn($!)
+			end
+		end
 	end
 TOPLEVEL_CLASS
 
diff -urN tdiary-3.0.1.orig/misc/plugin/disp_referrer.rb tdiary-3.0.1/misc/plugin/disp_referrer.rb
--- tdiary-3.0.1.orig/misc/plugin/disp_referrer.rb	2010-09-20 15:33:51.000000000 +0900
+++ tdiary-3.0.1/misc/plugin/disp_referrer.rb	2010-09-23 23:27:23.000000000 +0900
@@ -342,9 +342,9 @@
 		def self::unescape( str )
 			if str then
 				# escape ruby 1.6 bug.
-				str.gsub( /\+/, ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
-					[$1.delete('%')].pack('H*')
-				end
+				$KCODE = 'u'
+				require 'uri'
+				URI.unescape(str.gsub( /\+/, ' '))
 			else
 				''
 			end
diff -urN tdiary-3.0.1.orig/plugin/05referer.rb tdiary-3.0.1/plugin/05referer.rb
--- tdiary-3.0.1.orig/plugin/05referer.rb	2010-09-20 15:33:51.000000000 +0900
+++ tdiary-3.0.1/plugin/05referer.rb	2010-09-23 23:37:25.000000000 +0900
@@ -21,6 +21,8 @@
 	if @date then
 		diary = @diaries[@date.strftime( '%Y%m%d' )]
 		diary.clear_referers if diary
+	else
+		diary = @diaries[@diaries.keys.sort[-1]]
 	end
 	referer_update( diary )
 end
@@ -79,11 +81,14 @@
 		if @current_date then
 			@refs[@current_date].values.sort.reverse.each_with_index do |ary,idx|
 				break if idx >= limit
-				yield( ary[0], ary[1] )
+				yield( ary[0], ary[1], @current_date )
 			end
 		else
-			each_referer_orig( limit ) do |count, ref|
-				yield( count, ref )
+			@refs.keys.sort.each do |d|
+				@refs[d].values.sort.reverse.each_with_index do |ary,idx|
+					break if idx >= limit
+					yield( ary[0], ary[1], d )
+				end
 			end
 		end
 	end
@@ -113,8 +118,8 @@
 	case @mode
 	when 'latest'
 		if @cgi.referer and !@conf.referer_day_only then
-			referer_load_volatile( @referer_volatile )
-			referer_save_volatile( @referer_volatile, @cgi.referer )
+			referer_load_current( diary )
+			referer_save_current( diary, @cgi.referer )
 		end
 
 	when 'day'
@@ -124,6 +129,7 @@
 			referer_load_volatile( @referer_volatile )
 		elsif @cgi.referer
 			referer_load_volatile( @referer_volatile )
+			@referer_volatile.current_date = diary.date.strftime( '%Y%m%d' )
 			referer_save_volatile( @referer_volatile, @cgi.referer )
 		end
 
@@ -131,10 +137,12 @@
 		referer_load_current( diary )
 		referer_load_volatile( @referer_volatile ) if latest_day?( diary )
 
-	when /^(append|replace)$/
+	when 'append'
+		referer_load_volatile( @referer_volatile )
+		referer_save_volatile( RefererDiary::new( @conf.latest_limit ), nil )
+
+	when 'replace'
 		referer_load_volatile( @referer_volatile )
-		@referer_volatile.clear_oldest_referer( @date.strftime( '%Y%m%d' ) )
-		referer_save_volatile( @referer_volatile, nil )
 	end
 end
 
@@ -239,20 +247,28 @@
 
 	if diary and diary.count_referers != 0 then
 		result << %Q[<div class="caption">#{referer_today}</div>\n]
-		result << %Q[<ul>\n]
+		result << %Q[<script type="text/javascript">\n]
+		result << '//<![CDATA['
+		result << %Q[\ndocument.write('<ul>');\n]
 		diary.each_referer( limit ) do |count,ref|
-			result << %Q[<li>#{count} <a rel="nofollow" href="#{h ref}">#{h disp_referer( @referer_table, ref )}</a></li>\n]
+			result << %Q[document.write('<li>#{count} <a rel="nofollow" href="#{h ref}">#{h disp_referer( @referer_table, ref )}</a></li>');\n]
 		end
-		result << '</ul>'
+		result << %Q[document.write('</ul>');\n]
+		result << '//]]>'
+		result << %Q[\n</script>\n]
 	end
 
 	if @referer_volatile and latest_day?( diary ) and @referer_volatile.count_referers != 0 then
 		result << %Q[<div class="caption">#{volatile_referer}</div>\n]
-		result << %Q[<ul>\n]
-		@referer_volatile.each_referer( limit ) do |count,ref|
-			result << %Q[<li>#{count} <a rel="nofollow" href="#{h ref}">#{h disp_referer( @referer_table, ref )}</a></li>\n]
-		end
-		result << '</ul>'
+		result << %Q[<script type="text/javascript">\n]
+		result << '//<![CDATA['
+		result << %Q[\ndocument.write('<ul>');\n]
+		@referer_volatile.each_referer( limit ) do |count,ref,date|
+			result << %Q[document.write('<li><a href="#{h @index}#{anchor(date)}">#{date}</a> #{count} <a rel="nofollow" href="#{h ref}">#{h disp_referer( @referer_table, ref )}</a></li>');\n]
+		end
+		result << %Q[document.write('</ul>');\n]
+		result << '//]]>'
+		result << %Q[\n</script>\n]
 	end
 	result
 end
diff -urN tdiary-3.0.1.orig/tdiary/filter/spam.rb tdiary-3.0.1/tdiary/filter/spam.rb
--- tdiary-3.0.1.orig/tdiary/filter/spam.rb	2010-09-20 15:33:51.000000000 +0900
+++ tdiary-3.0.1/tdiary/filter/spam.rb	2010-09-23 23:38:47.000000000 +0900
@@ -362,6 +362,11 @@
 
 				return false if black_url?( referer )
 
+				if @bad_ips.detect {|p| p =~ @cgi.remote_addr}
+					debug( "ip address blacklisted: /#{p}/ =~ #{@cgi.remote_addr}" )
+					return false
+				end
+
 				if /#/ =~ referer then
 					debug( "referer has a fragment: #{referer}" )
 					return false
diff -urN tdiary-3.0.1.orig/tdiary.rb tdiary-3.0.1/tdiary.rb
--- tdiary-3.0.1.orig/tdiary.rb	2010-09-20 15:33:51.000000000 +0900
+++ tdiary-3.0.1/tdiary.rb	2010-09-24 01:55:27.000000000 +0900
@@ -1000,6 +1000,8 @@
 
 		def disp_referer( table, ref )
 			ref = @conf.to_native( CGI::unescape( ref ) )
+			ref.gsub!(/'/, "\\\\'")
+			ref.gsub!(/[\r\n]/, " ")
 			str = nil
 			table.each do |url, name|
 				if /#{url}/iu =~ ref then

