# -*- ruby -*-

require "resolv"

define_applicable_condition("Sendmail Compatible") do |condition|
  condition.description =
    "Make a milter depends on Sendmail workable with Postfix"

  netstat_connection_checker = manager.netstat_connection_checker
  dns_caches = {}
  max_n_dns_caches = 100

  guess_smtp_server_interface_ip_address = lambda do |client_address|
    netstat_connection_checker.smtp_server_interface_ip_address(client_address)
  end

  guess_smtp_server_interface_port = lambda do |client_address|
    netstat_connection_checker.smtp_server_interface_port(client_address)
  end

  resolve_host_name = lambda do |ip_address|
    return nil if ip_address.nil?
    begin
      address = (dns_caches[ip_address] ||= Resolv.getname(ip_address))
      dns_caches.clear if dns_caches.size >= max_n_dns_caches
      address
    rescue Resolv::ResolvError
      message = "[sendmail-compatible][warning] " +
        "can't resolve server name: <#{ip_address}>: <#{$!.message}>"
      Milter::Logger.warning(message)
      nil
    end
  end

  condition.define_connect_stopper do |context, host, address|
    if context.postfix?
      context["if_addr"] ||= guess_smtp_server_interface_ip_address.call(address)
      context["if_name"] ||= resolve_host_name.call(context["if_addr"])
      context["daemon_port"] ||= guess_smtp_server_interface_port.call(address)
    end
    false
  end

  condition.define_envelope_from_stopper do |context, from|
    context["i"] ||= "dummy-id" if context.postfix?
    false
  end
end
