#!/bin/bash

# Cdigos de salida
NOCARDFOUND=60
DETECTETHFAIL=61
SELECTETHFAIL=62
CANCELEXIT=63
SELECTCONFFAIL=64
NOROOT=65

LOG=/var/log/xnetworkconf
TMP=/tmp/xnetworkconf_prototipe

# Lista de funciones
# ==================
# checkid ----- Comprueba que el script es ejecutado por root
# checkip -----	Comprueba que el string pasado como argumento es una ip vlida, en caso contrario, vuelve a pedir una ip, devuelve la ip en IPOK
# removeconf --	Borra la configuracin en /etc/network/interfaces de la tarjeta de red seleccionada
# detecteth ---	Detecta las tarjetas de red en el sistema
# selecteth ---	Selecciona la tarjeta de red
# selectconf --	Elige configuracin Manual o Automtica
# ip ----------	Pregunta la direccin ip
# netmask -----	Pregunta la mscara de subred
# gateway -----	Pregunta la puerta de enlace
# dns ---------	Pregunta por un servidor de nombres
# dhcp --------	Configuracin dinmica
# static ------	Configuracin esttica
# main --------	Funcin principal

checkid ()
{
	if [ "$(whoami)" != "root" ]; then
		 Xdialog --stdout --title "xnetworkconf" \
					--backtitle "Permisos" \
					--msgbox "Necesitas permisos de root \
					para ejecutar este programa" 10 50
		exit $NOROOT
	fi
}

checkip ()
{
	IPTOCHECK="$1"
	CANDIDATE="$IPTOCHECK"

	while [ -z $(echo $IPTOCHECK | egrep '^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$') ]; do
		
		CANDIDATE=`Xdialog --stdout --title "xnetworkconf" \
			--backtitle "IP mal formada" --inputbox "La ip introducida \
			es incorrecta, debe de introducir cuatro nmeros de 0 a 255 tal que: x.x.x.x" 0 0 "$CANDIDATE"`

		[ "$?" = "1" ] && exit $CANCELEXIT

		IPTOCHECK="$CANDIDATE" 
	done

	IPOK="$IPTOCHECK"
}

removeconf ()
{
	HEREWEARE=0

	IFS=$'\n'
	for line in $(cat /etc/network/interfaces)
	do
		# La variable HEREWEARE nos indica si estamos en el "trozo" de fichero de configuracin de nuestra tarjeta.
		# Inicialmente vale 0.
		if [ "$HEREWEARE" = "0" ]; then
			# Si nos encontramos con nuestra tarjeta comentamos la linea y activamos HEREWEARE
			if [ -n "$(echo $line | grep $ETHSELECTED | grep -v ^#)" ]; then
				HEREWEARE=1
				echo "# $line" >> $TMP
			else
				echo $line >> $TMP
			fi
		# si $HEREWEARE = 1
		else 
			# si la siguiente linea pertenece a la configuracion de otra tarjeta, desactivamos HEREWEARE y la pasamos tal cual.
			if [ -n "$(echo $line | grep eth | grep -v $ETHSELECTED | grep -v ^#)" -o -n "$(echo $line | grep lo | grep -v ^#)" ]; then
				HEREWEARE=0
				echo $line >> $TMP
			# si la linea es un comentario, no la tratamos
			elif [ -n "$(echo $line | grep ^#)" ]; then
				echo $line >> $TMP

			# si la linea no es un comentario, ni pertenece a la configuracin de otra tarjeta, quiere decir que pertenece a la
			# configuracin de nuestra tarjeta y por tanto, la comentamos.
			else 
				echo "# $line" >> $TMP
			fi
		fi
		
	done
}

detecteth ()
{

	NUM_ETH=0
        for CARD in `cat /proc/net/dev | grep eth | awk '{print $1}' | cut -d : -f 1 | sort`
	do
		NUM_ETH=`expr $NUM_ETH + 1`
		ETH[$NUM_ETH]=$CARD
        done
	
        # Comprobar que disponemos de alguna tarjeta de red en el sistema

	if [ $NUM_ETH -lt 1 ]; then
                Xdialog --stdout --wrap --title "xnetworkconf" --backtitle \
                "Configuracin de red"  --msgbox "No se ha detectado que su sistema \
                disponga de ninguna tarjeta de red. Por tanto, la configuracin de red \
                no puede llevarse a cabo." 20 60
		
		exit $NOCARDFOUND
	fi
}

selecteth ()
{
	# Si tenemos ms de una tarjeta de red mostramos un men para seleccionar la tarjeta a configurar

	if [ $NUM_ETH -gt 1 ]; then
		CONT=1
		
		while [ $CONT -le $NUM_ETH ]
		do
			arg=$arg" ${ETH[$CONT]}"
			arg=$arg" \" \""
			CONT=`expr $CONT + 1`
		done
		
		ETHSELECTED=`eval Xdialog --stdout --title "xnetworkconf" \
			--backtitle '"Configuracin de red"' --menu\
			 '"Script de configuracin de red\n\
			Elija la interfaz de red que desea configurar:"' 20 70 7 \
			$arg`
	else
		# Si slo hay una tarjeta de red, ser eth0

		ETHSELECTED="eth0"
	fi
}

selectconf ()
{
	CONFSELECTED=`Xdialog --stdout --title "xnetworkconf" \
		--backtitle "Configuracin de red" --menu\
		"Script de configuracin de red\n\
		Elija una opcin:" 20 70 7  \
			"Automtica" "Obtener una direccin ip automticamente" \
			"Manual" "Configurar la red manualmente"`
	
	[[ "$?" = 1 || "$?" = 255 ]] && exit $CANCELEXIT
	return 0		
}

ip () 
{
	IP=`Xdialog --stdout  --title "xnetworkconf" \
		--backtitle "Direccin IP" --inputbox "Introduzca la direccin \
		IP que identificar a su ordenador" 0 0 $IP`
	
	[ "$?" = "1" ] && exit $CANCELEXIT

	# Comprobamos la ip, IPOK es nuestro "parmetro de salida" de la funcin checkip	
	checkip $IP
	IP="$IPOK"

	netmask
}

netmask ()
{
	if [ -z "$NM" ]; then
		NM="255.255.255.0"
	else
		# NM tiene una mala memoria..., as que le vamos a ayudar con NMAUX a recordar la seleccin del usuario.
		NMAUX="$NM"
	fi

	NM=`Xdialog --stdout --wizard --wrap --title "xnetworkconf" \
		--backtitle "Mscara de subred" --inputbox "Introduzca la mscara de \
		su red" 0 0 "$NM"`
	case $? in
		1)
			exit $CANCELEXIT 
			;;
		3)
			if [ -z "$NM" -a -n "$NMAUX" ]; then
				NM="$NMAUX"
			fi
			ip
			;;
		*)
			# Comprobamos la ip, IPOK es nuestro "parmetro de salida" de la funcin checkip
			checkip $NM
			NM="$IPOK"

			gateway
			;;
	esac
}

gateway () 
{
	# La siguiente linea, toma las tres primeras cifras de la ip puesta anteriormente, y se aade la ltima cifra, 1. Normalmente, esta ip es el gateway.

	if [ -z "$GW" ]; then
		GW="${IP%.*}.1"
	else
		# GW tiene una mala memoria.., as que le vamos a ayudar con GWAUX a recordar la seleccin del usuario.
		GWAUX="$GW"
	fi

	GW=`Xdialog --stdout --wizard --wrap --title "xnetworkconf" \
		--backtitle "Puerta de enlace" --inputbox "Introduzca la puerta de \
		enlace" 0 0 "$GW"`

	case $? in
		1)
			exit $CANCELEXIT
			;;
		3)
			if [ -z "$GW" -a -n "$GWAUX" ]; then
				GW="$GWAUX"
			fi
			netmask
			;;
		*)
			# Comprobamos la ip, IPOK es nuestro "parmetro de salida" de la funcin checkip
			checkip $GW
			GW="$IPOK"
			dns
			;;
	esac
}

dns ()
{
	DNS=`Xdialog --stdout --wizard --wrap --title "xnetworkconf" \
		--backtitle "Servidor DNS" --inputbox "Inserte la direccin de su servidor \
		de nombres DNS" 0 0 "$DNS"`
	case $? in
		1)
			exit $CANCELEXIT
			;;
		3)	
			gateway
			;;
		*)
			# Comprobamos la ip, IPOK es nuestro "parmetro de salida" de la funcin checkip
			checkip $DNS
			DNS="$IPOK"
			;;
	esac
}

dhcp ()
{
	Xdialog --stdout --ok-label "Si" --cancel-label "No" --wrap --title "xnetworkconf" \
		--backtitle "Configuracin de red" --yesno "Ha seleccionado una configuracin automtica para su \n\
		interfaz de red $ETHSELECTED. Desea aplicar los cambios?" 0 0
	[ "$?" -ne 0 ] && exit 0
	
	# Si ya existe una configuracion para nuestra tarjeta, la borramos.
	if [ -n "$( cat /etc/network/interfaces | grep $ETHSELECTED | grep -v ^#)" ]; then
		removeconf
	else
		cp /etc/network/interfaces $TMP	
	fi

	echo "auto $ETHSELECTED
iface $ETHSELECTED inet dhcp" >> $TMP 2>> $LOG

	cp $TMP /etc/network/interfaces
}

static ()
{
	# Llamamos a la funcin "ip", la primera de todas, las funciones se automantienen.
	ip

	Xdialog --stdout --ok-label "Si" --cancel-label "No" --wrap --title "xnetworkconf" \
		--backtitle "Configuracin de red" --yesno "A continuacin, se listan los datos \
		introducidos por usted, asegurese de que \
		son correctos:

		Tarjeta de red: $ETHSELECTED
		Direccin IP: $IP
		Mscara de red: $NM
		Puerta de enlace: $GW
		Servidor de nombres: $DNS

		Desea aplicar dicha configuracin?" 0 0

	[ "$?" -ne 0 ] && exit 0

	# Si ya existe una configuracion para nuestra tarjeta, la borramos.
	if [ -n "$( cat /etc/network/interfaces | grep $ETHSELECTED | grep -v ^#)" ]; then
		removeconf
	else
		cp /etc/network/interfaces $TMP
	fi

	# Escribimos los ficheros correspondientes...
	echo "iface $ETHSELECTED inet static
address $IP
netmask $NM
gateway $GW" >> $TMP 2>> $LOG
	echo "search nameserver $DNS" > /etc/resolv.conf 2>> $LOG

	cp $TMP /etc/network/interfaces
}

main () 
{
	checkid
	# Comprobamos si existe el fichero temporal, en ese caso lo borramos
	if [ -f $TMP ]; then
		rm $TMP
	fi

	# Detectamos las tarjetas disponibles, si no hay ninguna terminamos la aplicacin.
	detecteth
	[ "$?" != "0" ] && exit $DETECTETHFAIL
	
	# Seleccionamos la interfaz de red a configurar
	selecteth
	[ "$?" != "0" ] && exit $SELECTETHFAIL
	
	# Seleccionamos el tipo de configuracin
	selectconf
	[ "$?" != "0" ] && exit $SELECTCONFFAIL
	
	if [ "$CONFSELECTED" = "Automtica" ]; then
		dhcp
	elif [ "$CONFSELECTED" = "Manual" ]; then
		static
	fi

	# Comprobamos si existe el fichero temporal, en ese caso lo borramos
	if [ -f $TMP ]; then
		rm $TMP
	fi
}

# That's gonna be great!
# Let's go!

main

exit 0
