#!/usr/bin/ruby
#
# leases2tinydata - convert dhcpd.leases to tinydns datafile
#
# Copyright: Tatsuki Sugiura <sugi@nemui.org>
# License: GPL
#
# Usgae: leases2tinydata [lease file] [domain suffix]

class DHLease
#  include Enumerable
  
  def initialize(file)
    @ip = Hash.new
    parse(file)
  end

  def parse(file)
    current_ip = nil
    open(file).each do |line|
      if current_ip
	(key, value) = line.sub(/^\s+/,'').split(/\s+/,2)
	value.sub!(/;$/,'')
	value.chomp!
	if key == '}'
	  current_ip = nil
	  next
	elsif key == 'starts' || key == 'ends'
	  /\d (\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/ =~ value
	  @ip[current_ip][key] = Time.utc($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i)
	elsif key == 'hardware' || key == 'uid'
	  @ip[current_ip][key] = value
	elsif key == 'client-hostname'
	  @ip[current_ip]['host'] = value.gsub(/^"(.+)"$/,'\1')
	end
      elsif /lease\s+(\d{1,3}(?:\.\d{1,3}){3})\s+\{/ =~ line
	@ip[$1] = Hash.new
	current_ip = $1.clone
	  next
      end
    end
  end
  
  def each
    @ip.each do |ip, value|
      yield(ip, value)
    end
  end
end
  
class DdnsExport
  
  def initialize(lease = "/var/dhcp/dhcpd.leases", domain = "", expire = 300)
    @domain = domain
    @expire = expire
    begin
      @host = DHLease.new(lease)
    rescue
      puts "Can't open leases file, #{lease}"
      exit 1
    end
  end
  
  def export
    @host.each do |ip, value|
      next if !value.has_key?('host') || value['host'] == ""
      if ( Time.now > value['ends'] )
#        STDERR.puts "expired: #{value['host']}.#{@domain}(#{ip})"
      else
        puts("+#{value['host']}.#{@domain}:#{ip}:#{@expire}")
      end
    end
  end

end

ddns = DdnsExport.new((ARGV[0] || "/var/dhcp/dhcpd.leases"), ARGV[1], (ARGV[2] || 300).to_i)
ddns.export
