# common shell scripts functions for packaging list scripts
#

if [ -z "$home" ]
then
    echo >&2 "packages.rc: Botch: \$home not set"
    exit
fi

if [ ! -x $home/whatami ]
then
    echo >&2 "packages.rc: Botch: cannot find executable ../whatami"
    exit
fi

_setversions()
{
    [ -z "$tmp" ] && tmp=/var/tmp/$$
    $home/whatami \
    | awk '{ for (i = 3; i <= NF; i++) printf $i " "; print "" }' \
    | sed \
	-e 's/ \[.*//' \
	-e 's/ ([^)]*)//' \
	-e 's/RHEL Server/RHEL/' \
	-e 's/Arch Linux/ArchLinux /' \
	-e '/CentOS/{
s/CentOS Linux/CentOS/
s/CentOS\([0-9]\)/CentOS \1/
}' \
	-e '/Debian/{
s;bullseye/sid;11;
}' \
	-e '/FreeBSD/{
s/-RELEASE//
s/-p[0-9][0-9]*//
}' \
	-e '/SLES\([0-9][0-9]*\) SP/s//\1-SP/' \
	-e '/openSUSE/{
s/ Leap//
s/ Alpha//
}' \
	-e '/OpenIndiana/s/Hipster //' \
	-e '/OpenMandriva/{
s/ Lx//
s/ (Argon)//
}' \
	-e 's/^/arch=/' \
	-e 's/ /+distro=/' \
	-e 's/ / version="/' \
	-e 's/+distro/ distro/' \
	-e 's/$/"/' \
    | tr ' ' '\012' >$tmp.eval
    [ "$very_verbose" = "true" ] && echo >&2 "Info: `tr '\012' ' ' <$tmp.eval`"
    eval `cat $tmp.eval`
    full_version="$version"
    full_arch="$arch"
    rm -f $tmp.eval
}

# The require, unavailable and skip files have the same format,
# listing packages and package patterns that apply to a particular
# distribution, version and architecture.
#
# This function parses one of these files (specified as $1) and the
# selected packages (if any) are written on std output
#
_parse_file()
{
    [ -z "$tmp" ] && tmp=/var/tmp/$$
    rm -f $tmp.matches
    sed <$1 \
	-e 's/#.*//' \
	-e '/^[ 	]*$/d' \
    | while read distro_pat version_pat arch_pat packages
    do
	if echo "$distro" | grep "^$distro_pat" >/dev/null
	then
	    # Distro matches, check versions
	    #
	    _match=true
	    if [ "X$version_pat" = "X-" -o -z "$full_version" ]
	    then
		:
	    else
		if echo "$full_version" | grep "^$version_pat" >/dev/null
		then
		    :
		else
		    _match=false
		fi
	    fi
	    if $_match
	    then
		# Distro and version matches, check architecture
		if [ "X$arch_pat" = "X-" -o -z "$full_arch" ]
		then
		    :
		else
		    if echo "$full_arch" | grep "^$arch_pat" >/dev/null
		    then
			:
		    else
			_match=false
		    fi
		fi
	    fi
	    if $_match
	    then
		echo "$packages" >>$tmp.matches
	    fi
	fi
    done
    if [ -s $tmp.matches ]
    then
	tr '\012' ' ' <$tmp.matches
    else
	$very_verbose && echo >&2 "_parse_file: $1: no matches"
    fi
    rm -f $tmp.matches
}

# Larry Wall-style sniffing to discover primary IP addr and netmask
#
_getnetworkaddr()
{
    __verbose=false
    $very_verbose && __verbose=true
    if `which hostname >/dev/null 2>&1`
    then
	host=`hostname`
	if `which host >/dev/null 2>&1`
	then
	    host_out=`host $host`
	    if echo "$host_out" | grep ' has address ' >/dev/null
	    then
		addr=`echo "$host_out" | sed -e 's/.*address //'`
		$__verbose && echo "_getnetworkaddr: host -> addr=$addr" >&2
		if `which ifconfig >/dev/null 2>&1`
		then
		    # ifconfig line of interest looks like:
		    # inet 192.168.1.100  netmask 255.255.255.0  ...
		    # or
		    # inet addr:192.168.1.224  Bcast:192.168.1.255  Mask:255.255.255.0
		    # or
		    # inet 192.168.1.238/24 broadcast 192.168.1.255 flags 0x0
		    #
		    __config=`ifconfig | grep "[ :]$addr[ /]"`
		    if echo "$__config" | grep '[Mm]ask' >/dev/null
		    then
			mask=`echo "$__config" | sed -e 's/.*ask[ :]\([^ ][^ ]*\).*/\1/'`
		    elif echo "$__config" | grep " $addr/" >/dev/null
		    then
			mask=`echo "$__config" | sed -e '/\/24/s/.*/255.255.255.0/'`
		    else
			echo "_getnetworkaddr: botched config line: $__config" >&2
			mask=''
		    fi
		    $__verbose && echo "_getnetworkaddr: ifconfig -> mask=$mask" >&2
		    case "$mask"
		    in
			255.255.255.0|0xffffff00|ffffff00)	# /24 network
			    echo "$addr" | sed -e 's/\.[0-9]*$/.*/'
			    ;;
			# pmcd's [access] is not smart enough to handle other
			# than /24 networks, so map the other likely options
			# to the broader /24 network
			#
			255.255.255.128|255.255.255.192|255.255.255.224|255.255.255.240|255.255.255.248|255.255.255.252|255.255.255.254)
			    echo "$addr" | sed -e 's/\.[0-9]*$/.*/'
			    ;;
			*)
			    echo >&2 "_getnetworkaddr: Warning: cannot handle network mask: $mask"
			    ;;
		    esac
		elif `which ip >/dev/null 2>&1`
		then
		    # ip line of interest looks like:
		    # 4: br0    inet 192.168.1.100/24 ...
		    #
		    mask=`ip -f inet -o address | grep " $addr/" | sed -e 's/.*inet //' -e 's/[0-9.][0-9.]*\/\([^ ][^ ]*\) .*/\1/'`
		    $__verbose && echo "_getnetworkaddr: ip -> mask=$mask" >&2
		    if [ "$mask" != 24 ]
		    then
			# pmcd's [access] is not smart enough to handle other
			# than /24 networks, so map the other likely options
			echo >&2 "_getnetworkaddr: Warning: cannot handle network mask: $mask"
		    fi
		    # /24 netmask
		    mask=255.255.255.0
		    echo "$addr" | sed -e 's/\.[0-9]*$/.*/'
		else
		    echo >&2 "Neither ifconfig(1) nor ip(1)? Not sure how to get primary ip addr and netmask"
		fi
	    elif echo "$host_out" | grep ' not found: ' >/dev/null
	    then
		# container or dodgey network configuration ... see if
		# ip(1) can help out with a line like
		# 3: eth0    inet 10.88.0.2/16 ...
		#
		if `which ip >/dev/null 2>&1`
		then
		    ip -f inet -o addr | grep -v ': lo ' >$tmp.ip 2>&1
		    num_if=`wc -l <$tmp.ip | sed -e 's/ //g'`
		    if [ "$num_if" = 1 ]
		    then
			addr=`sed  <$tmp.ip -e 's/.* inet //' -e 's@/.*@@'`
			$__verbose && echo "_getnetworkaddr: ip -> addr=$addr" >&2
			echo "$addr"
			mask=`sed <$tmp.ip -e 's/.*inet //' -e 's/[0-9.][0-9.]*\/\([^ ][^ ]*\) .*/\1/'`
			if [ "$mask" != 24 ]
			then
			    echo >&2 "_getnetworkaddr: Warning: cannot handle network mask: $mask"
			fi
			# /24 netmask
			mask=255.255.255.0
			$__verbose && echo "_getnetworkaddr: ip -> mask=$mask" >&2
		    else
			echo >&2 "Unexpected ip(1) output: more than one line ..."
			cat >&2 $tmp.ip
		    fi
		else
		    echo >&2 "host(1) failed and ip(1) not installed ... cannot get ip_addr and netmask"
		fi
	    else
		echo >&2 "Unexpected host(1) output: $host_out ... cannot get ip addr and netmask"
	    fi
	else
	    echo >&2 "No host(1)? Not sure how to get primary ip addr and netmask"
	fi
    else
	echo >&2 "No hostname(1)? Not sure how to get primary ip addr and netmask"
    fi
}
