#!/bin/sh
# vim: set tabstop=4 shiftwidth=4 expandtab:
#
# This script generates proper /etc/resolv.conf and /etc/hosts
#

# PROVIDE: ya-resolvconf
# REQUIRE: ya-netif ya-routing
# KEYWORD: nojail
# BEFORE: NETWORKING

ya_os=$(uname -s)

case "${ya_os}" in
    Linux)
        ipv4_gw=$(ip -4 route list exact 0.0.0.0/0 scope global|grep -Ev "(lo|vlan|tun|tunl|ip6tnl|tap|vif|ipfw|pflog|virbr|plip|dummy)")
        ipv6_gw=$(ip -6 route list exact ::/0 scope global|grep -Ev "(lo|vlan|tun|tunl|ip6tnl|tap|vif|ipfw|pflog|virbr|plip|dummy)")
        protect_file="chattr +i"
        unprotect_file="chattr -i"
    ;;
    FreeBSD)
        ipv4_gw=$(route -n get -inet default 2>/dev/null)
        ipv6_gw=$(route -n get -inet6 default 2>/dev/null)
        protect_file="chflags schg"
        unprotect_file="chflags noschg"
    ;;
esac


test -f /etc/rc.conf.local && . /etc/rc.conf.local


configure_resolvconf()
{
    # Do not regenerate /etc/resolv.conf if "fix_resolvconf=NO" found in /etc/rc.conf.local
    case ${fix_resolvconf} in [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|[Nn]|0)
        echo "INFO: resolvconf configuration disabled in /etc/rc.conf.local"
        return 0
        ;;
    esac


    local _localresolver _resolv_conf _resolver _resolver64 _resolvers

    _resolv_conf="/etc/resolv.conf"


    # Check if someone uses local named or/and dns64 (IPv4 to IPv6 NAT). If yes - keep it!!!
    if grep -Eq ".*nameserver.*( 127.0.0.1| ::1)" ${_resolv_conf} ; then
        _localresolver="yes"
    fi

    case ${resolver64_enable} in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1)
        _resolver64="yes"
        ;;
    esac

    # if grep -Eq ".*nameserver.*2a02:6b8:0:3400::1023" ${_resolv_conf} ; then
    #     _resolver64="yes"
    # fi


    # If IPv4 networking detected, prefer to use IPv4 dns servers
    # If IPv4 networking NOT detected, but IPv6 found, use IPv6 dns servers
    # If something strange happend and neither IPv6 nor IPv4 networking found, generate mixed IPv4+IPv6 dns list
    if     [ ! -z "${ipv4_gw}" ] ; then
        _resolvers="141.8.146.1 213.180.205.1"
    elif   [ ! -z "${ipv6_gw}" ] ; then
        _resolvers="2a02:6b8:0:3400::1 2a02:6b8::1:1"
    else
        _resolvers="2a02:6b8:0:3400::1 141.8.146.1 2a02:6b8::1:1"
    fi


    # If we detected localresolver, use it first
    if     [ "${_localresolver}" = "yes" ] ; then
        _resolvers="127.0.0.1 ${_resolvers}"
    fi


    # If dns64 (IPv4 to IPv6 NAT) detected, use it first
    if [ "${_resolver64}" = "yes" ] ;then
        _resolvers="2a02:6b8:0:3400::1023 2a02:6b8:0:3400::1 2a02:6b8::1:1"
    fi


    #####################################
    # Here we generate /etc/resolv.conf #
    #####################################

    # prepare correct temporary file
    echo "# generated with $0 on $(date --rfc-3339=seconds)." > ${_resolv_conf}.tmp || return 1
    echo "search search.yandex.net yandex.ru" >> ${_resolv_conf}.tmp || return 1

    for _resolver in ${_resolvers} ; do
        echo "nameserver ${_resolver}" >> ${_resolv_conf}.tmp || return 1
    done

    echo "options timeout:1 attempts:1" >> ${_resolv_conf}.tmp || return 1

    # move new prepared file to /etc/resolv.conf
    ${unprotect_file} ${_resolv_conf} && mv ${_resolv_conf}.tmp ${_resolv_conf} && ${protect_file} ${_resolv_conf}

}


configure_hosts()
{
    # Do not regenerate /etc/hosts if "fix_hosts=NO" found in /etc/rc.conf.local
    case ${fix_hosts} in [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|[Nn]|0)
        echo "INFO: hosts configuration disabled in /etc/rc.conf.local"
        return 0
        ;;
    esac


    local _hosts _my_fqdn _my_shortname _my_ipv4_address _my_ipv6_address _ip4 _ip6

    _hosts="/etc/hosts"
    _my_fqdn=$(uname -n)
    _my_shortname=${_my_fqdn%%.*}

    if [ -z "${_my_fqdn}" -o -z "${_my_shortname}" ] ; then
        echo "error: cannot detect local hostname"
        return 1
    fi

    _my_ipv4_address=$(dig -t A +short +tries=10 "${_my_fqdn}" | grep -v ";")
    _my_ipv6_address=$(dig -t AAAA +short +tries=10 "${_my_fqdn}" | grep -v ";")


    if [ -z "${_my_ipv4_address}" -a -z "${_my_ipv6_address}" ] ; then
        echo "error: neither IPv4 nor IPv6 address was detected"
        return 0
    fi


    #####################################
    #    Here we generate /etc/hosts    #
    #####################################

    # prepare correct temporary file
    echo "# generated with $0 on $(date --rfc-3339=seconds)." > ${_hosts}.tmp || return 1
    echo "::1          localhost localhost.localdomain localhost6 localhost6.localdomain6" >> ${_hosts}.tmp || return 1
    echo "127.0.0.1    localhost localhost.localdomain localhost4 localhost4.localdomain4" >> ${_hosts}.tmp || return 1
    echo "" >> ${_hosts}.tmp || return 1

    # add IPv4 address to /etc/hosts if exists
    if [ ! -z "${_my_ipv4_address}" ] ; then
        # There might be multiple IPv4 adresses for hostname
        for _ip4 in ${_my_ipv4_address} ; do
            echo "${_ip4}                ${_my_fqdn} ${_my_shortname}" >> ${_hosts}.tmp || return 1
        done
    fi

    # add IPv6 address to /etc/hosts if exists
    if [ ! -z "${_my_ipv6_address}" ] ; then
        # There might be multiple IPv6 adresses for hostname
        for _ip6 in ${_my_ipv6_address} ; do
            echo "${_ip6}      ${_my_fqdn} ${_my_shortname}" >> ${_hosts}.tmp || return 1
        done
    fi

    # move new prepared file to /etc/hosts
    ${unprotect_file} ${_hosts} && mv ${_hosts}.tmp ${_hosts} && ${protect_file} ${_hosts}
}


case "$1" in
    start|stop|reload|restart)
        configure_resolvconf
        configure_hosts
    ;;

    *)
        echo "Usage: $0 {start|stop|restart|reload}" >&2
        exit 1
    ;;
esac

exit 0
