#!/bin/sh -e
#
# Author: Petter Reinholdtsen <pere@hungry.com>
# Date:   2002-08-06
#
# Set current hostname to match the IP address on eth0.  This is
# useful when getting the IP address from DHCP.

LC_ALL=C
export LC_ALL
QUIET=echo
USEMAC=false
onlyprint=false

DNSDOMAIN=intern

### IMPORTANT: We don't want this script to fail with a non-zero exitcode.
###            All problems should be reported as warnings, not errors.
###            See https://bugs.debian.org/1006604 for details.

log() {
    $QUIET "$2"
    logger -t update-hostname-from-ip "$1"
}

# Generate FQDN based on hardware MAC address
ether2hostname() {
    if [ "$1" ] ; then
        mac="$1"
    else
        mac=$(ip addr show ${INTERFACE} | grep 'link/ether ' | awk '{print $2; exit}')
    fi
    # Generate NetBIOS compliant hostname.
    mac=$(echo $mac | sed 's/[^0-9a-f-]//gi')
    if [ "$mac" ] ; then
       fqdn="am-$mac.$DNSDOMAIN";
       echo $fqdn
    fi
}

# Map IP to FQDN
ip2hostname() {
    ip=$1
    host $ip | grep 'domain name pointer' | cut -d ' ' -f 5 | \
        rev | cut -d '.' -f 2- | rev
}

PATH="/sbin:$PATH"

INTERFACE="$(ip -4 route | awk '/^default via / { print $5; exit }')"

if [ -z "$INTERFACE" ] ; then
    INTERFACE=eth0
fi

sethostname() {
    hostname="$1"
    namesource="$2"
    if hostname $hostname ; then
        echo $hostname > /etc/hostname
        log "info: changing hostname to $hostname based on $namesource"
    else
        log "warning: unable to set hostname to $hostname."
        return -1
    fi
}

# argument parsing
TEMP=$(getopt -n update-hostname-from-ip -o dmM:nI:q -- "$@")

# Abort when there was a bug
[ $? = 0 ] || die "error parsing arguments. Try $0 --help"

eval set -- "$TEMP"
while true; do
    case $1 in
        -m)
            USEMAC=true; shift; continue
            ;;
        -M)
            MAC="$2"; shift; shift; continue
            ;;
        -I)
            IP="$2"; shift; shift; continue
            ;;
        -q)
            QUIET=:; shift; continue
            ;;
        -n)
            onlyprint=true; shift; continue
            ;;
        --)
            # no more arguments to parse
            break
            ;;
        *)
            printf "Unknown option %s\n" "$1"
            exit 1
            ;;
    esac
done

# Extract current IP if non was provided on the command line
if [ -z "$IP" ] ; then
    IP=$(ip addr show ${INTERFACE} | grep 'inet ' | awk '{print $2; exit}' | cut -d "/" -f1)
fi

if [ "127.0.0.1" = "$IP" ] ; then
    IP=""
fi

if [ "$IP" ] ; then
    MY_HOSTNAME=$(ip2hostname $IP)
    SOURCE="reverse DNS of $IP"
fi

if $USEMAC && [ -z "$MY_HOSTNAME" ] ; then
    MY_HOSTNAME=$(ether2hostname $MAC)
    SOURCE="hardware MAC address"
fi

if [ "$MY_HOSTNAME" ]; then
    if $onlyprint ; then
        echo $MY_HOSTNAME
    else
        # Already got the correct host name?
        if [ "$MY_HOSTNAME" != "$(uname -n)" ] ; then
            sethostname "$MY_HOSTNAME" "$SOURCE"
        fi
    fi
else
    log "warning: failed to detect (and set) hostname from IP or MAC address"
fi

exit 0
