#@file    ogfunctions.lib
#@brief   Librería o clase para la generación del 1erFS 
#@class   client
#@brief   Funciones para la generación del primers sistema (initrd)
#@version 0.91
#@warning License: GNU GPLv3+




ogExportKernelParameters ()
{
	GLOBAL="cat /proc/cmdline"
	for i in `${GLOBAL}`
	do
		echo $i | grep "=" > /dev/null && export $i
	done
return 0
}

ogExportVarEnvironment ()
{
	#puntos de accesos al servidor ogprotocol=nfs
	export NFSROOTBOOT="/var/lib/tftpboot"
	export NFSCLIENTDIR="/opt/opengnsys/client"
	export NFSLOGDIR="/opt/opengnsys/log/clients"
	export NFSIMGDIR="/opt/opengnsys/images"
	#puntos de accesos al servidor ogprotocol=smb
	export SMBROOTBOOT="tftpboot"
	export SMBCLIENTDIR="ogclient"
	export SMBLOGDIR="oglog"
	export SMBIMGDIR="ogimages"

	#puntos de montaje local ram o cache
	export LOCALCLIENTDIR="/opt/opengnsys"
	export LOCALLOGDIR="/opt/opengnsys/log"
	export LOCALIMGDIR="/opt/opengnsys/images"
	export LOCALROOTBOOT="/opt/og2fs/tftpboot"		#punto de montaje del contendor tftpboot
	export LOCALROOTIMG="/opt/og2fs/2ndfs"			#punto de montaje donde se accede al 2nd FS mediante loop
	export LOCALROOTRAM="/opt/og2fs/1stfs"			#punto de montaje para unionfs
	export LOCALROOTUNION="/opt/og2fs/unionfs"		#punto de union entreo LOCALROOTIMG y LOCALROOTRAM
	##INFORMACION DE OTRAS VARIABLES OBTENDIAS EN OTRAS FUNCIONES.
	#ogGetROOTSERVER()  ip del servidor pxe, valor obtenido automaticamente desde dhcpd.
	#IPV4DDR
	#IPV4BROADCAST
	#IPV4NETMASK
	#IPV4GATEWAY
	#DNS0 	DNS1
	#HOSTNAME
	#ROOTSERVER  #ip del servidor pxe que ha servido el kernel
	#REPOSERVER=ogrepo  -> ogConectROOTSERVER() ip del servidor de images para separar serviicios.
	return 0
}

ogConfigureRamfs ()
{
	mkdir -p $LOCALROOTBOOT
	mkdir -p $LOCALROOTIMG
	mkdir -p $LOCALROOTRAM   			 
	mkdir -p $LOCALROOTUNION 
}

ogLoadNetModule ()
{
	#cargando netmodule
	if [ -n "$ognetmodule" ]
	then
   		echo "Cargando modulo de red $netmodule"
   		insmod `find /lib/modules/ -name ${netmodule}*`
	fi
}


ogPostConfigureFS()
{
	# configuramos el /etc/hostname.
	echo $HOSTNAME > /etc/hostname
	
	#configuramos el /etc/hosts
	echo "127.0.0.1 localhost" > /etc/hosts
	echo "$IPV4ADDR $HOSTNAME" >> /etc/hosts
	
	#configuramos el host.conf
	echo "order hosts,bind" > /etc/host.conf
	echo "multi on" >> /etc/host.conf
	
	# configuramos el /etc/networks
	#read -e NETIP NETDEFAULT <<<$(route -n | grep eth0 | awk -F" " '{print $1}')
	NETIP=$(route -n | grep eth0 | awk -F" " '{print $1}') && NETIP=$(echo $NETIP | cut -f1 -d" ")
	echo "default 0.0.0.0" > /etc/networks
	echo "loopback 127.0.0.0" >> /etc/networks
	echo "link-local 169.254.0.0" >> /etc/networks
	echo "localnet $NETIP" >> /etc/networks
	#route
}




ogGetROOTSERVER ()
{
	# get nfs root from dhcp
	if [ "x${NFSROOT}" = "xauto" ]; then
		# check if server ip is part of dhcp root-path
		if [ "${ROOTPATH#*:}" = "${ROOTPATH}" ]; then
			NFSROOT=${ROOTSERVER}:${ROOTPATH}
		else
			NFSROOT=${ROOTPATH}
		fi

	# nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
	elif [ -n "${NFSROOT}" ]; then
		# nfs options are an optional arg
		if [ "${NFSROOT#*,}" != "${NFSROOT}" ]; then
			NFSOPTS="-o ${NFSROOT#*,}"
		fi
		NFSROOT=${NFSROOT%%,*}
		if [ "${NFSROOT#*:}" = "$NFSROOT" ]; then
			NFSROOT=${ROOTSERVER}:${NFSROOT}
		fi
	fi
	export ROOTSERVER
return 0
}	

ogConectROOTSERVER ()
{
local OPTIONS
#params a detectar
if [ $ogrepo ]
then
	# Validar si la ip es correcta
	ROOTREPO=$ogrepo
else
	ROOTREPO=$ROOTSERVER
fi

case "$ogprotocol" in
	cdrom)
		echo  "Montar imagen de CD-ROM"
		blkid /dev/s*
		mount -t iso9660 LABEL=ogClient $LOCALROOTBOOT
		;;    
	httfs)
		echo "protocolo httfs aun no soportado"
		;;
	sshfs)
		echo "protocolo sshfs aun no soportado"
		;;
	smb)    
		echo "Preparando conexión con el Repositorio $ROOTSERVER por $ogprotocol"
		OPTIONS=" -o user=opengnsys,pass=og"
		mount.cifs //${ROOTSERVER}/${SMBCLIENTDIR} $LOCALCLIENTDIR $OPTIONS 
		mount.cifs //${ROOTSERVER}/${SMBLOGDIR} $LOCALLOGDIR $OPTIONS 
		mount.cifs //${ROOTSERVER}/${SMBROOTBOOT} $LOCALROOTBOOT $OPTIONS 
		mount.cifs //${ROOTREPO}/${SMBIMGDIR} $LOCALIMGDIR ${OPTIONS},ro 
		;;
	nfs)
		echo "Preparando conexión con el Repositorio $ROOTSERVER por $ogprotocol"
		nfsmount -o nolock,ro $ROOTSERVER:$NFSCLIENTDIR $LOCALCLIENTDIR
		nfsmount -o nolock $ROOTSERVER:$NFSLOGDIR $LOCALLOGDIR
		nfsmount -o nolock $ROOTSERVER:$NFSROOTBOOT $LOCALROOTBOOT
		nfsmount -o nolock,ro $ROOTREPO:$NFSIMGDIR $LOCALIMGDIR
		;;
esac
}

ogMerge2ndFile()
{
if [ -f $LOCALROOTBOOT/ogclient/ogclient.sqfs ]
then	
	cat /proc/mounts > /tmp/mtab.preunion
	if [ "$og2nd" == "img" ]
	then
		#para acceder al img
		losetup /dev/loop0 $LOCALROOTBOOT/ogclient/ogclient.img -o 32256
		mount /dev/loop0 $LOCALROOTIMG
	else
		## para acceder al squashfs
		mount $LOCALROOTBOOT/ogclient/ogclient.sqfs $LOCALROOTIMG -t squashfs -o loop
	fi
	for i in etc var lib bin sbin usr root boot; do
		unionmount $i
	done
	cat /tmp/mtab.preunion > /etc/mtab
else
	echo "Fichero imagen del cliente no encontrado"
	return 1
fi
}


unionmount()
{
	tmpdir=/$1		#dir
	FUSE_OPT="-o default_permissions -o allow_other -o use_ino -o nonempty -o suid"
	UNION_OPT="-o cow -o noinitgroups"
	UBIN="unionfs-fuse"
					#UPATH="/unionfs"
					#LOCALROOTIMG="/opt/og2fs/2ndfs"	
					#LOCALROOTRAM="/opt/og2fs/1stfs"		#/unionfs/host	#punto de montaje para unionfs
					#LOCALROOTUNION=/opt/og2fs/unionfs/"	#/unionfs/union	#punto de union entreo LOCALROOTIMG y LOCALROOTRAM
					#mkdir -p $LOCALROOTRAM   			 #/unionfs/host
					#mkdir -p $LOCALROOTUNION 			  #/unionfs/union
	mkdir -p $LOCALROOTRAM$tmpdir
	#mount --bind /$tmpdir $LOCALROOTRAM$tmpdir
	U1STDIR="${LOCALROOTRAM}${tmpdir}=RW"
	U2NDDIR="${LOCALROOTIMG}${tmpdir}=RO"
	UNIONDIR=$LOCALROOTUNION$tmpdir
	mkdir -p $UNIONDIR
	$UBIN $FUSE_OPT $UNION_OPT ${U1STDIR}:${U2NDDIR} $UNIONDIR
	mount --bind  $UNIONDIR $tmpdir
}


unionmountOLD()
{
	FUSE_OPT="-o default_permissions -o allow_other -o use_ino -o nonempty -o suid"
	UNION_OPT="-o cow -o noinitgroups"
	UPATH="/unionfs"
	UBIN="unionfs-fuse"
	mkdir -p /unionfs/host
	mkdir -p /unionfs/union
	dir=$1
	mkdir -p /unionfs/host/$dir
	#mount --bind /$dir /unionfs/host/$dir
	mkdir -p /unionfs/union/$dir
	host="/unionfs/host/${dir}=RW"
	common="/opt/og2fs/${dir}=RO"
	$UBIN $FUSE_OPT $UNION_OPT ${host}:${common} /unionfs/union/$dir
	mount --bind  /unionfs/union/$dir /$dir
}

ogconfigure_lo()
{
# for the portmapper we need localhost
ifconfig lo 127.0.0.1
#/etc/init.d/portmap start
}

ogconfigure_networking()
{
IP=$IPOPTS
# http://paste.ubuntu.com/427631/  Paste from yofel at Tue, 4 May 2010 13:49:56 +0000
        if [ -n "${BOOTIF}" ]; then
                # pxelinux sets BOOTIF to a value based on the mac address of the
                # network card used to PXE boot, so use this value for DEVICE rather
                # than a hard-coded device name from initramfs.conf. this facilitates
                # network booting when machines may have multiple network cards.
                # pxelinux sets BOOTIF to 01-$mac_address

                # strip off the leading "01-", which isn't part of the mac
                # address
                temp_mac=${BOOTIF#*-}

                # convert to typical mac address format by replacing "-" with ":"
                bootif_mac=""
                IFS='-'
                for x in $temp_mac ; do
                        if [ -z "$bootif_mac" ]; then
                                bootif_mac="$x"
                        else
                                bootif_mac="$x:$bootif_mac"
                        fi
                done
                unset IFS

                # look for devices with matching mac address, and set DEVICE to
                # appropriate value if match is found.
                for device in /sys/class/net/* ; do
                        if [ -f "$device/address" ]; then
                                current_mac=$(cat "$device/address")
                                if [ "$bootif_mac" = "$current_mac" ]; then
                                        DEVICE=${device##*/}
                                        break
                                fi
                        fi
                done
        fi

        # networking already configured thus bail out
        [ -n "${DEVICE}" ] && [ -e /tmp/net-"${DEVICE}".conf ] && return 0

        # support ip options see linux sources
        # Documentation/filesystems/nfsroot.txt
        # Documentation/frv/booting.txt

        for ROUNDTTT in 2 3 4 6 9 16 25 36 64 100; do

                # The NIC is to be configured if this file does not exist.
                # Ip-Config tries to create this file and when it succeds
                # creating the file, ipconfig is not run again.
                if [ -e /tmp/net-"${DEVICE}".conf ]; then
                        break;
                fi

            case ${IP} in
		    none|off)
			# Do nothing
			;;
		    ""|on|any)
			# Bring up device
			echo "Setting $DEVICE with kernel params $IP: ipconfig -t ${ROUNDTTT} ${DEVICE} "
			ipconfig -t ${ROUNDTTT} ${DEVICE}
			;;
		    dhcp|bootp|rarp|both)
			echo "Setting $DEVICE with (dhcp) kernel params $IP: ipconfig -t ${ROUNDTTT} -c ${IP} -d ${DEVICE} "
			ipconfig -t ${ROUNDTTT} -c ${IP} -d ${DEVICE}
			;;
		    *)
			echo "Setting $DEVICE with kernel params $IP: ipconfig -t ${ROUNDTTT} -d $IP  "
			ipconfig -t ${ROUNDTTT} -d $IP

			# grab device entry from ip option
			NEW_DEVICE=${IP#*:*:*:*:*:*}
			if [ "${NEW_DEVICE}" != "${IP}" ]; then
				NEW_DEVICE=${NEW_DEVICE%:*}
			else
				# wrong parse, possibly only a partial string
				NEW_DEVICE=
			fi
			if [ -n "${NEW_DEVICE}" ]; then
				DEVICE="${NEW_DEVICE}"
			fi
			;;
               esac
        done

        # source ipconfig output
        if [ -n "${DEVICE}" ]; then
                # source specific bootdevice
                . /tmp/net-${DEVICE}.conf
        else
                # source any interface as not exaclty specified
                . /tmp/net-*.conf
        fi
}

   #####################################################################
# Ask yesno question.
#
# Usage: yesno OPTIONS QUESTION
#
#   Options:
#     --timeout N    Timeout if no input seen in N seconds.
#     --default ANS  Use ANS as the default answer on timeout or
#                    if an empty answer is provided.
#
# Exit status is the answer.  0=yes 1=no

ogYesNo()
{
    local ans
    local ok=0
    local timeout=0
    local default
    local t

    while [[ "$1" ]]
    do
        case "$1" in
        --default)
            shift
            default=$1
            if [[ ! "$default" ]]; then error "Missing default value"; fi
            t=$(echo $default | tr '[:upper:]' '[:lower:]')

            if [[ "$t" != 'y'  &&  "$t" != 'yes'  &&  "$t" != 'n'  &&  "$t" != 'no' ]]; then
                error "Illegal default answer: $default"
            fi
            default=$t
            shift
            ;;

        --timeout)
            shift
            timeout=$1
            if [[ ! "$timeout" ]]; then error "Missing timeout value"; fi
            #if [[ ! "$timeout" =~ ^[0-9][0-9]*$ ]]; then error "Illegal timeout value: $timeout"; fi
            shift
            ;;

        -*)
            error "Unrecognized option: $1"
            ;;

        *)
            break
            ;;
        esac
    done

    if [[ $timeout -ne 0  &&  ! "$default" ]]; then
        error "Non-zero timeout requires a default answer"
    fi

    if [[ ! "$*" ]]; then error "Missing question"; fi

    while [[ $ok -eq 0 ]]
    do
        if [[ $timeout -ne 0 ]]; then
            if ! read -t $timeout -p "$*" ans; then
                ans=$default
            else
                # Turn off timeout if answer entered.
                timeout=0
                if [[ ! "$ans" ]]; then ans=$default; fi
            fi
        else
            read -p "$*" ans
            if [[ ! "$ans" ]]; then
                ans=$default
            else
                ans=$(echo $ans | tr '[:upper:]' '[:lower:]')
            fi 
        fi

        if [[ "$ans" == 'y'  ||  "$ans" == 'yes'  ||  "$ans" == 'n'  ||  "$ans" == 'no' ]]; then
            ok=1
        fi

        if [[ $ok -eq 0 ]]; then warning "Valid answers are: yes y no n"; fi
    done
    [[ "$ans" = "y" || "$ans" == "yes" ]]
}
     

