#!/bin/bash
#
# 	DESCRIPTION:	configure network services	
#
#	SCRIPT NAME:	configure_network.sh
#
#	Input:	argument
#		[--help] show usage
#		<-t|--type> "static" or "dynamic"
#		static argument:
#			<-h|--hostname> hostname
#			<-i|--ip> ip address
#			<-n|--netmask> netmask
#			<-g|--gateway> gateway 
#			<-d|--domainname> domainname
#			[-p|--pdns] priamaryDNS
#			[-s|--sdns] secondaryDNS
#			[-e|--device] network device. if no configure, default is eth0.
#		dynamic argument:
#			<-h|--hostname> hostname
#			[-e|--device] network device. if no configure, default is eth0.
#
#	Output:	
#			NULL
#	Return value:
#			1 argument error
#			2 ip/netmask/gateway address incorrect
#			3 hosts/resolv.conf/ifcfg.template/network doesn't exist
#
#	AUTHOR:		Qin Bo
#
#	EMAIL:		bqin@linx-info.com
#
#	DATE:		2010-08-23
#
#	HISTORY:
#	REVISOR		DATE			MODIFICATION
#	Qin Bo		2010-08-23		create
#
#
#

source ./functions

usage ()
{
	if [ "$1" == "-n" ];then
		cmd="info"
		ret=0
	else
		cmd="err"
		ret=1
	fi

	$cmd "
This script will configure your network

Usage: $0 options:

options:
	[--help] show this message
	<-t|--type> \"static\" or \"dynamic\"
	static argument:
	<-h|--hostname> hostname
	<-i|--ip> ip address
	<-n|--netmask> netmask
	<-g|--gateway> gateway 
	[-d|--domainname] domainname
	[-p|--pdns] priamaryDNS
	[-s|--sdns] secondaryDNS
	[-e|--device] network device. if no configure, default is eth0.
	dynamic argument:
	<-h|--hostname> hostname
	[-e|--device] network device. if no configure, default is eth0.
	"
	return $ret
}

check_ip ()
{

	if [ $# -ne 1 ];then
		err "$FUNCNAME function argument error, it must 1 argument !"
		return 1;
	fi

	local  ip=$1
	local  ret=2

	# "=~" use for match regular expression, only use in bash 3.0 or higher
	if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then

		# IFS is a separator for read builtin command, we save old IFS
		OIFS=$IFS
		IFS='.'
		# set $ip to ip array
		ip=($ip)
		# restore IFS
		IFS=$OIFS
		[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
		&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
			ret=$?
	fi

	return $ret

}

parse_arg ()
{
	if [ $# -eq 0 ];then
		usage
		return 1
	fi

	tmp=$(getopt -o t:h:d:i:n:g:p:s:e:? --long type:,hostname:,domainname:,ip:,netmask:,gateway:,pdns:,sdns:,device:,help -- "$@" 2>>$DEV_LOG)
	if [ $? -ne 0 ];then
		usage
		return 1
	fi

	# set all argument to arg variable
	eval set -- "$tmp"

	while true ; do
		case $1 in
			-t|--type) TYPE="$2" ; 
				info  "network configure type: $TYPE" ;
				shift 2;;
			-h|--hostname) HOSTNAME="$2"; 
				info "hostname: $HOSTNAME" ; 
				shift 2 ;;
			-d|--domainname) DOMAINNAME="$2"; 
				info "domainname: $DOMAINNAME" ; 
				shift 2 ;;
			-i|--ip) IP="$2"; 
				info "ip: $IP" ; 
				shift 2 ;;
			-n|--netmask) NETMASK="$2"; 
				info "netmask: $NETMASK" ; 
				shift 2 ;;
			-g|--gateway) GATEWAY="$2"; 
				info "gateway: $GATEWAY" ; 
				shift 2 ;;
			-p|--pdns) primaryDNS="$2"; 
				info "primaryDNS: $primaryDNS" ; 
				shift 2 ;;
			-s|--sdns) secondaryDNS="$2"; 
				info "secondaryDNS: $secondaryDNS" ; 
				shift 2 ;;
			# may be have mulit-network devices
			-e|--device) DEVICE="$2"; 
				info "device: $DEVICE" ; 
				shift 2 ;;
			# shift the last "--", this dash is define by getopt (more information see man getopt)
			--) shift ;break;;
			--help) usage -n ;return 0;;
			*) usage ;return 1;;
		esac
	done

	if [ "$TYPE" != "static" -a "$TYPE" != "dynamic" ];then
		err "configure network must be static or dynamic"
		return 1
	fi

 	if [ -z "$HOSTNAME" ];then
		err "HOSTNAME can't be empty"
		return 1
	fi

	# default device is eth0
 	if [ -z "$DEVICE" ];then
		DEVICE="eth0"
	fi

	if [ "$TYPE" == "static" ];then
		if [ -z "$IP" ];then
			err "static configure network, IP address can't be empty"
			return 1
		else 
			info "checking ip: $IP"
			if ! check_ip "$IP"; then
				err "ip: $IP incorrect"
				return 2
			fi
		fi
		if [ -z "$NETMASK" ];then
			err "static configure network, netmask address can't be empty"
			return 1
		else 
			info "checking netmask: $NETMASK"
			if ! check_ip "$NETMASK"; then
				err "netmask: $NETMASK incorrect"
				return 2
			fi
		fi
		if [ -z "$GATEWAY" ];then
			err "static configure network, gateway address can't be empty"
			return 1
		else 
			info "checking gateway: $GATEWAY"
			if ! check_ip "$GATEWAY"; then
				err "gateway: $GATEWAY incorrect"
				return 2
			fi
		fi
	fi

}

# configure /etc/hosts
configure_hosts ()
{
	if [ -e "$TARGET/etc/hosts" ];then
		if [ "$TYPE" == "static" ];then
			sed -i "s/^#<ip-address>/$IP/
				s/<hostname\.domain\.org>/$HOSTNAME\.$DOMAINNAME/
				s/<hostname>/$HOSTNAME/"	"$TARGET/etc/hosts"
		elif [ "$TYPE" == "dynamic"  ];then
			printf "%s\n" $HOSTNAME >> "$TARGET/etc/hosts"
		fi
	else
		err "$TARGET/etc/hosts doesn't exist"
		return 3
	fi
}

# configure /etc/resolv.conf
configure_resolv_conf ()
{
	if [ -e "$TARGET/etc/resolv.conf" ];then
		if [ "$TYPE" == "static" ];then
			sed -i "s/^#search <domain\.org>$/search $DOMAINNAME/
				s/^#domain <domain\.org>$/domain $DOMAINNAME/" "$TARGET/etc/resolv.conf"
			if [ -n "$primaryDNS" ];then
				sed -i "s/^#nameserver <ip-address>$/nameserver $primaryDNS/" "$TARGET/etc/resolv.conf"
			fi
			if [ -n "$secondaryDNS" ];then
				sed -i "/nameserver/a\nameserver $secondaryDNS" "$TARGET/etc/resolv.conf"
			fi
		fi
	else
		err "$TARGET/etc/resolv.conf doesn't exist"
		return 3
	fi
}

# configure /etc/sysconfig/network-devices/ifcfg.$DEVICE
configure_ifcfg ()
{
	if [ -e "$IFCFG_TEMP" ];then
		if [ "$TYPE" == "static" ];then
			SERVICE="ipv4-static"
			BOOTPROTO="none"
			BROADCAST=$(./ipcalc.pl -n $IP/$NETMASK| grep Broadcast|awk '{ print $2 }')
			NETWORK=$(./ipcalc.pl -n $IP/$NETMASK| grep Network|awk '{ print $2 }'|cut -d "/" -f 1)
		elif [ "$TYPE" == "dynamic" ];then
			SERVICE="dhcpcd"
			BOOTPROTO="dhcp"
			IP=""
			NETMASK=""
			GATEWAY=""
			BROADCAST=""
			NETWORK=""
		fi

		sed "/DEVICE/ c\DEVICE=$DEVICE
			/BOOTPROTO/ c\BOOTPROTO=$BOOTPROTO
			/SERVICE/ c\SERVICE=$SERVICE
			/IPADDR/ c\IPADDR=$IP
			/NETMASK/ c\NETMASK=$NETMASK
			/GATEWAY/ c\GATEWAY=$GATEWAY
			/BROADCAST/ c\BROADCAST=$BROADCAST
			/NETWORK/ c\NETWORK=$NETWORK
			" "$IFCFG_TEMP" >"$NETWORK_DEVICES_DIR/ifcfg-$DEVICE"
	else
		err "$IFCFG_TEMP doesn't exist"
		return 3
	fi	
}

# configure /etc/sysconfig/network
configure_network_file ()
{
	if [ -e "$SYSCONFIG_DIR/network" ];then
		if [ "$TYPE" == "static" ];then
			sed -i "/HOSTNAME/ c\HOSTNAME=$HOSTNAME" "$SYSCONFIG_DIR/network"
			printf "DOMAIN=%s\n" "$DOMAINNAME" >>"$SYSCONFIG_DIR/network"
		elif [ "$TYPE" == "dynamic" ];then
			sed -i "/HOSTNAME/ c\HOSTNAME=$HOSTNAME" "$TARGET/etc/sysconfig/network"
		fi
	else
		err "$SYSCONFIG_DIR/network doesn't exist"
		return 3
	fi

}

configure_network ()
{
	configure_hosts

	configure_resolv_conf

	configure_ifcfg
	
	configure_network_file
}

main ()
{
	info "configure network"
	parse_arg "$@"
	erv
	configure_network
	erv
	info "configure network success"
}

TYPE=""
HOSTNAME=""
DOMAINNAME=""
IP=""
NETMASK=""
GATEWAY=""
primaryDNS=""
secondaryDNS="" 
DEVICE=""
SERVICE=""
BROADCAST=""
BOOTPROTO=""
NETWORK=""

SYSCONFIG_DIR="$TARGET/etc/sysconfig"
NETWORK_DEVICES_DIR="$SYSCONFIG_DIR/network-devices"
IFCFG_TEMP="$NETWORK_DEVICES_DIR/ifcfg.template"

# The quotes around '$@' are essential!
# in this way we can accept whitespace as parameter.
main "$@"


