#!/bin/sh

PROG="${0##*/}" #program name

print_version()
{
	cat <<EOF
$PROG version @VERSION@

Written by Stanislav Ievlev

Copyright (C) 2003-2004 ALT Linux Team
EOF
	exit
}


print_usage()
{
	[ "$1" = 0 ] || exec >&2
	cat <<EOF
Usage: $PROG [options] 

alterator backend for simple etcnet configuration

Valid options are:
  -h, --help	display help screen
  -v, --version	display version information
  -l, --list	get list of available intefaces
  -t, --type	check for existance
  -d, --delete	(empty action, required for backend)
  -r, --read	read general network or network interface information
  -w, --write	modify general network or network interface information

Report bugs to <inger@altlinux.org>
EOF
	[ -n "$1" ] && exit "$1" || exit
}


iface_name()
{
	echo $1|sed 's,ifaces/,,'
}

add_or_subst()
{
	local name=$1
	local value=$2
	local file=$3

	[ -f "$file" ] || touch "$file"
	if grep -qs "^$name" "$file";then
		/bin/sed -r -i "s,^$name.*,$name$value," $file
	else
		echo "$name$value">>$file
	fi
}

find_nameserver()
{
	grep -n ^nameserver /etc/resolv.conf|sed -n "$1 s/^\([^:]\+\):.*/\1/p"
}

replace_nameserver()
{
	local l=$(find_nameserver $1)
	[ -n "$l" ] && sed -i "$l s,^nameserver.*,nameserver $2," /etc/resolv.conf
}

#check for dhcp usage
has_dhcp()
{
	local list=$(find /etc/net/ifaces/  -name 'options'|
			egrep -v '(default|unknown)/options')
	if grep -qs "^BOOTPROTO=dhcp$" $list 2>/dev/null; then
		echo "yes"
	else
		echo "no"
	fi
}

#reconfigure network
reload_network()
{
	/sbin/service network reload &>/dev/null
}

send_notification()
{
	dbus-send --system /org/altlinux/alterator/network \
	org.altlinux.network string:changed
}


#try to get hostname from dns
#TODO: run resolver using exectimer
try_resolv()
{
	#reload network at first time
	[ -f /var/lock/TMP_1ST ] && reload_network
	grep -qs "^nameserver" /etc/resolv.conf &&
	/sbin/ip addr show |
		sed -ne 's,^[[:space:]]*inet[[:space:]]\+\([^/]\+\).*,\1,p'|
		grep -v '^127\.'|
		head -n1|
		xargs -r resolve -s
}


add_to_hosts()
{
	local host_name="$1" && shift

	grep -qs "^[^#]*\<$host_name\>" /etc/hosts && return 0
	
	if grep -qs "^127.0.0.1" /etc/hosts;then
		sed -r "s,^127\.0\.0\.1[[:space:]]*(.*)$,127.0.0.1	$host_name \1," -i /etc/hosts
	else
		printf '127.0.0.1\t%s\n' "$host_name" >> /etc/hosts
	fi
}

addressmask="[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
netconfig=/etc/sysconfig/network

TEMP=`getopt -n $PROG -o h,v,l:,d:,r:,w:,t: -l help,version,list:,delete:,read:,write:,type: -- "$@"` || print_usage
eval set -- "$TEMP"

while :; do
	case "$1" in
		-h|--help) print_usage 0
			;;
		-v|--version) print_version
			;;
		-l|--list)
			shift;dir="$1";
			if [ "$dir" == "/" ] ;then
				echo "ifaces d"
				echo "general r"
			elif [ "$dir" == "ifaces" ];then
				/sbin/ip link|egrep '^[[:digit:]]+'|
					sed -r 's,^[[:digit:]]+\:[[:space:]]+([^:]+).*,\1,'|
					grep -v '^lo'|
					sed 's,.*,& r,'
			fi
			;;
		-d|--delete)
			#ignore
			shift;dir="$1";
			;;
		-t|--type)
			shift;dir="$1";
			if [ "$dir" = "ifaces" ]; then
				echo "ifaces d"
			elif [ "$dir" = "general" ]; then
				echo "general r"
			else
				name=$(iface_name "$dir")
				/sbin/ip li|grep -qs -E "^[[:digit:]]+:[[:space:]]+$name:" && echo "$dir r"
			fi
			;;
		-r|--read)
			shift;dir="$1";
			if echo "$dir"|grep -qs ifaces; then
				name=$(iface_name "$dir")
				if [ -f "/etc/net/ifaces/$name/ipv4address" ] ;then
					echo -n "ipv4address:"
					cat "/etc/net/ifaces/$name/ipv4address" |
						grep -E "$addressmask"
				else
					addr=$(/sbin/ip addr show $name |
					          grep inet|head -n1|
						  sed -r 's,[[:space:]]*inet[[:space:]]+([^[:space:]]+)[[:space:]].*,\1,')
					echo "ipv4address:"$addr
				fi
				description=$(/usr/bin/ifaceinfo $name)
				echo "description:$description"
				if grep -qs "^BOOTPROTO=dhcp$" /etc/net/ifaces/$name/options 2>/dev/null; then
					echo "dhcp:yes"
				else
					echo "dhcp:no"
				fi
			elif echo "$dir"|grep -qs general; then
				unset HOSTNAME
				unset DOMAINNAME
				[ -f $netconfig ] && . $netconfig

				dhcp_test=$(has_dhcp)
				
				#searching for any dhcp - specially for simple interface
				echo "dhcp:$dhcp_test"
				
				#retrieve hostname and domainname
				if [ -z "$HOSTNAME" -a "$dhcp_test" = "yes" ] ;then
					HOSTNAME=$(try_resolv)
					DOMAINNAME=${HOSTNAME#*.}
				fi

				echo "hostname:$HOSTNAME"
				echo "domainname:$DOMAINNAME"

				#retrieve nameservers
				grep -w ^nameserver /etc/resolv.conf|
					sed s,nameserver[[:space:]]*,,|
					grep -n '.*'|sed 's,.*,dns&,'
				count=$(grep -w ^nameserver /etc/resolv.conf|wc -l)
				if [ $count -eq "1" ]; then
					echo "dns2:"
				elif [ $count -eq "0" ];then
					echo "dns1:"
					echo "dns2:"
				fi
				
				#calculate default gateway
				gw=$(find  /etc/net/ifaces/ -name 'ipv4route' -exec cat {} ';'|
					grep default|head -n1|
					sed -r 's,default[[:space:]]+via[[:space:]]+,,')

				if [ -z "$gw" -a "$dhcp_test" = "yes" ] ;then
					gw=$(/sbin/ip route list|
						grep default|head -n1|
						sed -r 's,.*default[[:space:]]+via[[:space:]]+([^[:space:]]+)[[:space:]]*.*,\1,')
				fi
				echo "gateway:$gw"
			fi
			;;
		-w|--write)
			shift;dir="$1";
			if [ "$dir" = "general" ];then
				while read l;do
					option=${l%%:*}
                                        value=${l#*:}
					[ -n "$value" ] &&
					case "$option" in
						dns1)
							if grep -qs ^nameserver /etc/resolv.conf; then
								replace_nameserver 1 $value
							else
								echo "nameserver $value">>/etc/resolv.conf
							fi
							;;
						dns2)
							l=$(find_nameserver 2)
							if [ -n "$l" ]; then
								replace_nameserver 2 $value
							else
								echo "nameserver $value">>/etc/resolv.conf
							fi
							;;
						hostname)
							add_or_subst "HOSTNAME=" "$value" $netconfig
							hostname "$value"
							echo $value >/etc/HOSTNAME
							add_to_hosts "$value"
							;;
						domainname)
							add_or_subst "DOMAINNAME=" "$value" $netconfig
							add_or_subst "search " "$value" "/etc/resolv.conf"
							;;
						gateway)
						#calulate default gateway's interface and modify
							reload_network
							iface=$(/sbin/ip route get $value |sed -ne 's/^[^ ]\+ dev \([^ ]\+\) .*/\1/p;q'|tail -n1)
							if [ -n "$iface" ]; then
								ifacedir="/etc/net/ifaces/$iface"
								[ -d "$ifacedir" ] || mkdir -p "$ifacedir"
								
								add_or_subst "default via " "$value" "$ifacedir/ipv4route"
							fi
							;;
						*)
						;;
					esac
	
				done
			elif echo $dir|grep -qs ifaces; then
				name=$(iface_name "$dir")
				etcnetdir="/etc/net/ifaces/$name"
				[ -d "$etcnetdir" ] || mkdir -p "$etcnetdir"
				while read l;do
					option=${l%%:*}
                                        value=${l#*:}
					[ "$option" = "ipv4address" ] && echo "$value" >"$etcnetdir/ipv4address"
					[ "$option" = "dhcp" ] && 
					if [ "$value" = "yes" ]; then
						add_or_subst "BOOTPROTO=" "dhcp" $etcnetdir/options
					elif [ "$value" = "no" ]; then
						add_or_subst "BOOTPROTO=" "static" $etcnetdir/options
					fi
					[ "$option" = "use_hotplug" ] &&
					if [ "$value" = "yes" ]; then
						add_or_subst "USE_HOTPLUG=" "yes" $etcnetdir/options
					elif [ "$value" = "no" ]; then
						add_or_subst "USE_HOTPLUG=" "no" $etcnetdir/options
					fi
				done
			fi
			reload_network
			send_notification
			;;
		--) shift; break
			;;
		*) Fatal "unrecognized option: $1"
			;;
	esac
	shift
done
