#!/usr/bin/ruby

=begin
Purpose:
  Updates GeoIP Country (paid) database from MaxMind.com. Requires
  valid license key to work.

Why:
  1) I hate the idea of running some weird C code ("geoipupdate")
     from cron, that's why.
  2) I don't want to run "geoipupdate" on all machines using this DB.

Author: Wejn <wejn at box dot cz>
License: GPLv2 (without the "latter" option)
Requires: Ruby >= 1.8, geoip country license (to be of any value)
TS: 20060626181500
=end

# your license key here
$license_key = 'You-wish :-)'

# destination file
$outfile = '/usr/share/GeoIP/GeoIP.dat'

# temp file -- MUST BE on same filesystem as $outfile
$tmpfile = '/usr/share/GeoIP/GeoIP.dat.tmp'

require 'digest/md5'
require 'open-uri'
require 'zlib'
require 'stringio'

# Fetch GeoIP country file from MaxMind
def get_result_for(key, md5) #{{{1
    url = "ht" + "tp://www.maxmind.com/app/update?"
    url += "license_key=#{key}&md5=#{md5}"

    content = nil
    open(url) do |io|
        compr = StringIO.new(raw = io.read)
        if compr.read(2) == "\x1f\x8b"
            compr.rewind
            gz = Zlib::GzipReader.new(compr)
            content = gz.read
            gz.close
        else
            content = raw
        end
    end

    content
end # }}}1

puts "Begin." if $VERBOSE

begin
    omd5sum = Digest::MD5.hexdigest(File.open($outfile, 'r').read) rescue nil
    content = get_result_for($license_key, omd5sum)

    if content =~ /No new updates available/
        puts "No new updates ..." if $VERBOSE
        exit 0
    end

    md5sum = Digest::MD5.hexdigest(content)
    content2 = get_result_for($license_key, md5sum)
rescue
    puts "Error:  Problem fetching file! >> #{$!} (#{$!.class})"
    exit 1
end

puts "Fetched." if $VERBOSE

if content2 =~ /No new updates available/
    begin
        File.open($tmpfile, 'w') do |f|
            f.write(content)
        end
        File.unlink($outfile) if FileTest.exists?($outfile)
        File.rename($tmpfile, $outfile)
    rescue
        puts "Error: Problem updating file! >> #{$!} (#{$!.class})"
        exit 1
    end
else
    puts "Error: Problem refreshing GeoIP -- new file fails MD5 check!"
    exit 1
end

puts "Updated." if $VERBOSE
exit 0