#!/bin/sh
#
# Copyright (c) 2002, Sun Microsystems, Inc.  All rights reserved.
#
# ResolveName.sh
#
# Script for resolving a system name or IP address into the
# corresponding fully-qualified domain name or IP address.
#
###########################################################
# SETTINGS:

# General settings:
# -----------------

PATH='/usr/sbin:/usr/bin:$PATH'

# Agent configuration file, if available...
if [ "%${SRMAGT_CONFIG_PATH}" = "%" ]
then
    AGENT_CONFIG_FILE=""
else
    AGENT_CONFIG_FILE=${SRMAGT_CONFIG_PATH}/uagent.cfg
fi

# Resolution namespaces and search order...
SEARCH_ENUM_HOSTS="HOSTS"
SEARCH_ENUM_DNS="DNS"
SEARCH_ENUM_NIS="NIS"
SEARCH_ORDER_DEFAULT="$SEARCH_ENUM_DNS,$SEARCH_ENUM_NIS,$SEARCH_ENUM_HOSTS"
SEARCH_ORDER=""
SEARCH_ORDER_SETTING="SRMAGT_RESOLVENAME_ORDER"

# Command-line options...
OPT_ADDR="a"
OPT_NAME="n"
OPT_ORDER="o"
OPT_DOMAIN="d"
OPT_IPADDR="i"
OPT_HELP="h"
OPT_FOR_GETOPTS="$OPT_ADDR:$OPT_NAME:$OPT_ORDER:$OPT_DOMAIN:$OPT_IPADDR$OPT_HELP"

# Configuration flags...
ARG_IPADDR=0
ARG_HOSTNAME=0
ARG_VALUE=""
RESOLVE_FQDN=1

# HOSTS defaults:
# ---------------
HOSTS_FILE=/etc/hosts
HOSTS_AVAILABLE=0

# DNS defaults:
# -------------
DNS_RESOLV_CONF=/etc/resolv.conf
DNS_AVAILABLE=0

# NIS defaults:
# -------------
NIS_AVAILABLE=0
NIS_DEFAULT_DOMAIN=""

###########################################################
# FUNCTIONS:

print_usage()
{
    echo ""
    echo "Use: $0 -a <IP address> | -n <hostname>"
    echo "        [-d <default domain>]"
    echo "        [-o <search order>]"
    echo "        [-i]"
    echo ""
    echo "  -a <IP address>     = IP address to resolve."
    echo "  -n <hostname>       = Host name to resolve."
    echo "  -d <default domain> = (optional) Override domain for NIS search."
    echo "  -o <search order>   = (optional) Comma-separated list"
    echo "                        specifying the search order.  Values"
    echo "                        can include $SEARCH_ENUM_NIS, $SEARCH_ENUM_DNS and/or $SEARCH_ENUM_HOSTS."
    echo "                        (Default = \"$SEARCH_ORDER_DEFAULT\")"
    echo "  -i                  = (optional) Resolve to IP address instead"
    echo "                        of fully-qualified host name."
    echo ""
    echo "  Returned status values:"
    echo "    0   Successfully resolved given name or IP address."
    echo "    1   Invalid option specified."
    echo "    2   Parameter value was invalid."
    echo "    255 Name or IP address could not be resolved."
    echo ""
}

initialize_search_order()
{
    # If there's a known Agent configuration file, check to see
    # if it contains a new default search order for us...
    SEARCH_ORDER=""
    if [ "%$AGENT_CONFIG_FILE" != "%" ]
    then
	if [ -s $AGENT_CONFIG_FILE ]
	then
	    # Attempt to grep out the search order setting...
	    TMP_SO=`grep -v "^#" $AGENT_CONFIG_FILE | grep "^[ ]*$SEARCH_ORDER_SETTING[ ]* " | awk '{print $2}'`
	    if [ "%$TMP_SO" != "%" ]
	    then
		SEARCH_ORDER=$TMP_SO
	    fi
	fi
    fi

    # If we didn't find a setting in the Agent configuration file,
    # use the default search order.
    if [ "%$SEARCH_ORDER" = "%" ]
    then
	SEARCH_ORDER=$SEARCH_ORDER_DEFAULT
    fi
}

# Returns 1 if a valid namespace, 0 if not.
validate_hosts()
{
    # Confirm existence of the hosts file...
    if [ ! -s $HOSTS_FILE ]
    then
	return 0
    fi

    # If we get here, the namespace is valid.
    return 1
}

# Returns 1 if a valid namespace, 0 if not.
validate_dns()
{
    # Confirm existence of resolver configuration file...
    if [ ! -s $DNS_RESOLV_CONF ]
    then
	return 0
    fi

    # If we get here, the namespace is valid.
    return 1    
}

# Returns 1 if a valid namespace, 0 if not.
validate_nis()
{
    # Verify NIS utilities and services are installed...
    pkginfo -q SUNWnisu
    if [ $? -ne 0 ]
    then
	return 0
    fi

    # Confirm there is a default server available...
    #ypwhich 1>/dev/null 2>&1
    #if [ $? -ne 0 ]
    #then
	return 0
    #fi

    # If we get here, the namespace is valid.
    return 1
}

###########################################################
# MAIN:

# Initialize settings...
initialize_search_order

# Process parameters...
while getopts $OPT_FOR_GETOPTS tmpopt
do
    case $tmpopt in

    $OPT_ADDR) ARG_VALUE=$OPTARG
	       ARG_IPADDR=1;;

    $OPT_NAME) ARG_VALUE=$OPTARG
	       ARG_HOSTNAME=1;;

    $OPT_ORDER) SEARCH_ORDER=$OPTARG;;

    $OPT_DOMAIN) NIS_DEFAULT_DOMAIN=$OPTARG;;

    $OPT_IPADDR) RESOLVE_FQDN=0;;

    $OPT_HELP) print_usage
	       exit 0;;
    \?) print_usage
	exit 1;;
    esac
done

# Validate parameters...

if [ $ARG_IPADDR -eq 0 -a $ARG_HOSTNAME -eq 0 ]
then
    echo "ERROR: You must specify either an IP address or host name!"
    exit 2
fi

if [ $ARG_IPADDR -ne 0 -a $ARG_HOSTNAME -ne 0 ]
then
    echo "ERROR: You cannot specify both an IP address and host name!"
    exit 2
fi

if [ "%$SEARCH_ORDER" = "%" ]
then
    echo "ERROR: You cannot specify an empty namespace search order!"
    exit 2
fi

if [ "%$NIS_DEFAULT_DOMAIN" != "%" ]
then
    if [ ! -d /var/yp/binding/$NIS_DEFAULT_DOMAIN ]
    then
	echo "ERROR: The specified NIS domain name is not known!"
	exit 2
    fi
fi

# Validate namespace availablility...

validate_hosts
HOSTS_AVAILABLE=$?

validate_dns
DNS_AVAILABLE=$?

validate_nis
NIS_AVAILABLE=$?

# Process search order...
FULL_SEARCH_ORDER=`echo "$SEARCH_ORDER" | awk -F"," '{ for( i = 1; i <= NF;i++ ) printf("%s ", $i) }'`

# Search for the answer...
RESOLVED_VALUE=""
for searchopt in $FULL_SEARCH_ORDER
do
    case $searchopt in

    $SEARCH_ENUM_HOSTS)
	if [ $HOSTS_AVAILABLE -ne 0 ]
	then
	    if [ $ARG_IPADDR -ne 0 ]
	    then 
		GREP_FILTER="^$ARG_VALUE"
	    else
		GREP_FILTER="-w $ARG_VALUE"
	    fi

	    if [ $RESOLVE_FQDN -ne 0 ]
	    then
		AWK_FILTER='{print $2}'
	    else
		AWK_FILTER='{print $1}'
	    fi

	    RESOLVED_VALUE=`grep -v '^#' $HOSTS_FILE | grep $GREP_FILTER | awk "$AWK_FILTER"`
	    if [ $? -ne 0 ]
	    then
		RESOLVED_VALUE=""
	    fi
	fi
	;;

    $SEARCH_ENUM_NIS)

	if [ $NIS_AVAILABLE -ne 0 ]
	then
	    if [ $ARG_IPADDR -ne 0 ]
	    then
		NIS_TABLE="hosts.byaddr"
	    else
		NIS_TABLE="hosts.byname"
	    fi
	    if [ $RESOLVE_FQDN -ne 0 ]
	    then
		AWK_FILTER='{print $2}'
	    else
		AWK_FILTER='{print $1}'
	    fi

	    if [ "%$NIS_DEFAULT_DOMAIN" = "%" ]
	    then
		NIS_DEFAULT_DOMAIN=`domainname`
		NIS_DOMAIN_SEARCH=`nisdefaults -s | awk '{printf("%s ", substr( $i, 0, length($1)-1 ) ) }'`
	    else
		NIS_DOMAIN_SEARCH=$NIS_DEFAULT_DOMAIN
	    fi

	    TMP_VALUE=""
	    for tmpdomain in $NIS_DOMAIN_SEARCH
	    do
		TMP_VALUE=`ypmatch $ARG_VALUE.$tmpdomain $NIS_TABLE 2>/dev/null | awk "$AWK_FILTER"`
		if [ "%$TMP_VALUE" != "%" ]
		then
		    break
		fi
	    done

	    if [ "%$TMP_VALUE" != "%" ]
	    then
		if [ $RESOLVE_FQDN -ne 0 ]
		then
		    # If NIS returned a dotted name, we assume it has
		    # already been qualified and leave it alone.
		    TMP_ISDOTTED=`echo $TMP_VALUE | grep -c "\."`
		    if [ $TMP_ISDOTTED -eq 0 ]
		    then
			RESOLVED_VALUE=$TMP_VALUE.$NIS_DEFAULT_DOMAIN
		    else
			RESOLVED_VALUE=$TMP_VALUE
		    fi
		else
		    RESOLVED_VALUE=$TMP_VALUE
		fi
	    fi
	fi
	;;

    $SEARCH_ENUM_DNS)
	
	if [ $DNS_AVAILABLE -ne 0 ]
	then
	    if [ $RESOLVE_FQDN -ne 0 ]
	    then
		GREP_FILTER="Name:"
		AWK_FILTER='{print $2}'
	       
	    else
		GREP_FILTER="Address:"
		AWK_FILTER='{if(NR > 1) print $2}'
	    fi

	    RESOLVED_VALUE=`nslookup $ARG_VALUE 2>/dev/null | grep "$GREP_FILTER" 2>/dev/null | awk "$AWK_FILTER"`
	    if [ $? -ne 0 ]
	    then
		RESOLVED_VALUE=""
	    fi
	fi
	;;

    *) echo "ERROR: Invalid namespace search order option \"$searchopt\"!"
       exit 2;;
    esac

    if [ "%$RESOLVED_VALUE" != "%" ]
    then
	break
    fi
done

if [ "%$RESOLVED_VALUE" = "%" ]
then
    echo "Failed to resolve given name or address!"
    exit 255
fi
echo $RESOLVED_VALUE | awk '{ print $1 }'
exit 0
