#!/usr/bin/env bash
#
# Copyright 2008-2015 VMware, Inc.  All rights reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#
# set the hostname of the machine.
#
# $1 == FQDN (Fully Qualified Domain Name)
#

export TEXTDOMAINDIR=/opt/vmware/lib/locale
export TEXTDOMAIN=vami_set_hostname

VAMI_EDIT_BEGIN_MARK="# VAMI_EDIT_BEGIN"
VAMI_EDIT_NOTES="# Generated by Studio VAMI service. Do not modify manually."
VAMI_EDIT_END_MARK="# VAMI_EDIT_END"

#remove vami section, and any lines matching the common localhost pattern, both will be replaced
CUT_VAMI_SECTION="sed -r -e '/$VAMI_EDIT_BEGIN_MARK/,/$VAMI_EDIT_END_MARK/d' -e '/(127.0.0.1|::1)\s+.*/d'"

VAMI_BIN=/opt/vmware/share/vami
VAMI_IP_ADDR="$VAMI_BIN/vami_ip_addr"
VAMI_IP6_ADDR="$VAMI_BIN/vami_ip6_addr"
VAMI_DEFAULT_INTERFACE="$VAMI_BIN/vami_default_interface"

IPV4HOSTNAME=
IPV6HOSTNAME=
DEFAULT_INT=
DEFAULT_IPV4=
DEFAULT_IPV6=
FQDN=
HN=
DN=

. $VAMI_BIN/vami_common

usage()
{
    echo Usage: $0 [-h] FQDN
}

while getopts h: c
do
    case $c in
        h) usage; exit 0 ;;
        ?) usage; exit 1 ;;
    esac
done

shift $(($OPTIND - 1))

PASSED_NAME="$1"
regex='^[a-zA-Z0-9_][a-zA-Z0-9_\.\-]*$'
if [[ "$PASSED_NAME" != "" && ! $PASSED_NAME =~ $regex ]]
then
    echo "Exit, invalid hostname $PASSED_NAME ."
    exit 1
fi

SYSCONFIG_NETWORK_FILE=/etc/sysconfig/network

HOSTFILE=/etc/hosts
# For SLES we need to update /etc/HOSTNAME
if [ -d /etc/sysconfig/network ]
then
    HOSTNAMEFILE=/etc/HOSTNAME
else
    HOSTNAMEFILE=/etc/hostname
fi
MAILNAME=/etc/mailname

if vami_check_access -rw $HOSTFILE
then
    :;
else
    exit 1
fi

if [ "$PASSED_NAME" = "" ]; then
 #
 # Perform DNS reverse lookup on hostname from the IP address.
 # Wait for a max of 15 seconds with 1 retry.
 # If it can't be resolved, skip setting the hostname.
 #
 # prefer an IPv4 reverse lookup over an IPv6 reverse lookup
 #
    DEVICE=$($VAMI_DEFAULT_INTERFACE)

    # avoid get inative ip on photon
    sleep 1

    IPV4_ADDR=$($VAMI_IP_ADDR $DEVICE)
    if [[ $? -eq 0 && -n $IPV4_ADDR ]]; then
       NAME=$(host -W 15 -R 1 -T $IPV4_ADDR 2>/dev/null)
       if [ $? -eq 0 ]; then
         IPV4HOSTNAME=`echo $NAME | awk '{print $NF}' | sed -e 's/\.$//' -e 1q`
       else
         echo "DNS reverse lookup on $IPV4_ADDR has failed."
       fi
    fi

    IPV6_ADDR=$($VAMI_IP6_ADDR $DEVICE)
    if [[ $? -eq 0 && -n $IPV6_ADDR ]]; then
       NAME=$(host -W 15 -R 1 -T $($VAMI_IP6_ADDR $DEVICE) 2>/dev/null)
       if [ $? -eq 0 ]; then
         IPV6HOSTNAME=`echo $NAME | awk '{print $NF}' | sed -e 's/\.$//' -e 1q`
       else
         echo "DNS reverse lookup on $IPV6_ADDR has failed."
       fi
    fi
else
 #If this script is called with a hostname then, we'll use that name instead
 #of the lookup.
    IPV4HOSTNAME="$PASSED_NAME"
    IPV6HOSTNAME="$PASSED_NAME"
fi

set_ipv4() {
    echo "== set_ipv4 =="
    echo "DEFULT_INT: $DEFAULT_INT"
    echo "DEFAULT_IPV4: $DEFAULT_IPV4"
    echo "HN: $HN"
    echo "DN: $DN"
    echo -e "==============\n"

    if [[ -z $DEFAULT_IPV4 ]]; then
        return
    fi

    if [[ -z $HN ]]; then
        echo "set_ipv4: No hostname available! Only setting loopback."
        echo "127.0.0.1  localhost" >> $HOSTFILE
        return
    fi

    local hostAndDomain=
    if [[ ( $HN != *$DN ) && ( -n $DN ) ]]; then
        hostAndDomain="$HN.$DN"
    fi

    echo "127.0.0.1  $hostAndDomain $HN localhost" >> $HOSTFILE

    # Set default IPv6 loopback.
    if [[ -z $DEFAULT_IPV6 ]]; then
        echo "::1  $hostAndDomain $HN localhost ipv6-localhost ipv6-loopback" \
            >> $HOSTFILE
    fi
}

set_ipv6() {
    echo "== set_ipv6 =="
    echo "DEFULT_INT: $DEFAULT_INT"
    echo "DEFAULT_IPV6: $DEFAULT_IPV6"
    echo "HN: $HN"
    echo "DN: $DN"
    echo -e "==============\n"

    if [[ -n $DEFAULT_IPV6 ]]; then
        if [[ -z $HN ]]; then
            echo "set_ipv6: No hostname available! Only setting loopback."
            echo "::1 localhost ipv6-localhost ipv6-loopback" >> $HOSTFILE
            return
        fi

        local hostAndDomain=
        if [[ ( $HN != *$DN ) && ( -n $DN ) ]]; then
            hostAndDomain="$HN.$DN"
        fi

        echo "::1  $hostAndDomain $HN localhost ipv6-localhost ipv6-loopback" \
            >> $HOSTFILE
    fi

    #Set loopback and domain pointing to 127.0.0.1 so ipv4 based commands work
    if [[ -z $DEFAULT_IPV4 ]]; then
        echo "127.0.0.1  $hostAndDomain $HN localhost" >> $HOSTFILE
    fi
}

set_hostname()
{
    DEFAULT_INT=$($VAMI_DEFAULT_INTERFACE)
    DEFAULT_IPV4=$($VAMI_IP_ADDR $DEFAULT_INT)
    DEFAULT_IPV6=$($VAMI_IP6_ADDR $DEFAULT_INT)

    # Skip setting hostname if DNS reverse lookup does not function.
    if [[ -z $IPV4HOSTNAME && -z $IPV6HOSTNAME ]]; then
        echo "Unable to obtain hostname from DNS reverse lookup."
        echo "Please exam DNS/network configuration."
        echo "Skip setting hostname."
        return
    fi

    cp $HOSTFILE ${HOSTFILE}.orig
    local cmd="$CUT_VAMI_SECTION ${HOSTFILE}.orig > $HOSTFILE"
    eval $cmd

    echo "$VAMI_EDIT_BEGIN_MARK" >> $HOSTFILE
    echo "$VAMI_EDIT_NOTES" >> $HOSTFILE

    # Update hosts with ipv4 settings if any
    if [ -n "$IPV4HOSTNAME" ]; then
        HN=`vami_hname "$IPV4HOSTNAME"`
        DN=`vami_domain "$IPV4HOSTNAME"`
        set_ipv4
    fi

    # Update hosts with ipv6 settings if any
    if [ -n "$IPV6HOSTNAME" ]; then
        HN=`vami_hname "$IPV6HOSTNAME"`
        DN=`vami_domain "$IPV6HOSTNAME"`
        set_ipv6
    fi
    echo "$VAMI_EDIT_END_MARK" >> $HOSTFILE

    # Use ipv4 setting for hostname first if zero use ipv6
    if [ -n "$IPV4HOSTNAME" ]; then
        FQDN="$IPV4HOSTNAME"
    else
        FQDN="$IPV6HOSTNAME"
    fi
    echo "$FQDN" > $HOSTNAMEFILE

    hostname -F $HOSTNAMEFILE

    NEWFQDN=`hostname -f`

    if [ "$NEWFQDN" = "$FQDN" ]; then
        #Let's print and log the hostname
        vami_log notice Host name has been set to $FQDN
        echo `gettext "Host name has been set to"` $FQDN

        if vami_check_access -rw $MAILNAME 2>/dev/null
        then
            echo "$FQDN" > $MAILNAME
        fi

        # Update the /etc/sysconfig/network file for centos/redhat based OS's
        # This code is traversed for both DHCP (we lookup hostname from DNS) and
        # Static IP (we can be called either with hostname or we do a lookup)
        if [ -f "$SYSCONFIG_NETWORK_FILE" ]
        then
            sed --in-place=.horig "s/^HOSTNAME=.*$/HOSTNAME=$HN/" $SYSCONFIG_NETWORK_FILE
            sed --in-place=.dorig "s/^DOMAINNAME=.*$/DOMAINNAME=$DN/" $SYSCONFIG_NETWORK_FILE
        fi

        return 0
    fi

    return 1
}

CURRENT_HOSTNAME=`hostname -f`

RET=1
if set_hostname
then
    RET=0
fi

if [ "$RET" -eq 1 ]; then
    #The hostname command may fail, reset it back to a valid hostname
    echo `gettext "Unable to set hostname to"` ${HOSTNAME}, `gettext " reverting to previous hostname:"` $CURRENT_HOSTNAME
    IPV4HOSTNAME=$CURRENT_HOSTNAME
    IPV6HOSTNAME=$CURRENT_HOSTNAME
    set_hostname
fi

exit $RET
