#!/bin/sh
#

control_c()
{
    echo 
    echo "Restarting recovery process."
    echo

    sleep 1

    killall -9 bash
}

trap control_c 1 2 3 15

if [ -f /etc/init.d/platform_params ]; then
        . /etc/init.d/platform_params
else
        echo "/etc/init.d/platform_params must exist to use $0"; exit 1
fi

if [ -f /opt/meru/etc/flash_defs.sh ]; then
        . /opt/meru/etc/flash_defs.sh
else
        echo "/opt/meru/etc/flash_defs.sh must exist to use $0"; exit 1
fi

set_platform_params

export PATH=$PATH:/opt/meru/bin
export TARGET_TMPDIR=/tmp/setup
mkdir -p $TARGET_TMPDIR

export TARGET_IFCG=$TARGET_TMPDIR/ifcfg-

TMP=$TARGET_TMPDIR/sysinit_$$
ethfile=${TARGET_IFCG}${REAL_IF}

HOSTNAME=`hostname`

TOTALBAR=40
BARINTERVAL=30
ITRBAR=0

# Prompts the user if they really want to proceed (because it will take services down)
promptyn()
{
    while true
    do
        echo -n "$1 [y/n]:"
        read -e INPUT
        echo $INPUT | grep '^[yY]$' >/dev/null 2>&1 && return 0
        echo $INPUT | grep '^[yY][eE][sS]$' >/dev/null 2>&1 && return 0
        echo $INPUT | grep '^[nN]$' >/dev/null 2>&1 && return 1
        echo $INPUT | grep '^[nN][oO]$' >/dev/null 2>&1 && return 1

        echo "Error: Unrecognized input $INPUT"
        return -1
        echo
    done
}

prompt_number()
{
    while true
      do
      echo -n "Please type [1-3]: "
      read -e INPUT
      [ "$INPUT" ] || continue
      [ `echo $INPUT | wc -L` -gt 128 ] && {
          echo "Error: Maximum line size exceeded."
          continue
      }

      if [ "$INPUT" == "1" -o "$INPUT" == "2" -o "$INPUT" == "3" ]; then
          return $INPUT
      fi

      echo 
      echo "That is not a valid selection." 
      echo 

    done
}

prompt()
{
    while true
    do
        echo -n "$1: "
        read -e INPUT
        [ "$INPUT" ] || continue
        [ `echo $INPUT | wc -L` -gt 128 ] && {
            echo "Error: Maximum line size exceeded."
            continue
        }
        return 1
    done
}

# Prints the bar for the copy progress..
print_bar() {
	echo -e -n "\rCopying Data:  "
	for (( i = 0; i < $ITRBAR; i++ ))
	do
		echo -n "#"
	done
}

finish_bar() {
	ITRBAR=$TOTALBAR
	print_bar
	echo
}

valid_ip()
{
    vip=$1
    ip_fail=false
    parts=0
    excessive_parts=`echo $vip | sed -e "s/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*//"`
    if [ "$excessive_parts" ]; then
	ip_fail=true
    else
	for iptok in `echo $vip | sed 's/\./ /g'`
	do
	    expr $iptok + 1 >/dev/null 2>&1 || {
		ip_fail=true
		break
	    }
	    [ $iptok -gt 255 ] && {
		ip_fail=true
		break
	    }
	    parts=`expr $parts + 1`
	done
    fi
    [ $parts -eq 4 ] || ip_fail=true

    if [ "$vip" = "0.0.0.0" ]; then
       echo "Error: Invalid IP Addres($vip)."
       echo "Please enter this value again."
       return 1
    fi
    if [ "$vip" = "255.255.255.255" ]; then
       echo "Error: Invalid IP Addres($vip)."
       echo "Please enter this value again."
       return 1
    fi
    if [ "$vip" = "224.0.0.0" ]; then
       echo "Error: Invalid IP Addres($vip)."
       echo "Please enter this value again."
       return 1
    fi
    
    [ "$ip_fail" = "false" ] && return 0

    echo "Error: $vip does not appear to be a valid ipv4 style address."
    echo "Please enter this value again."
    return 1
}

valid_netmask_value()
{
    vip=$1
    ip_fail=false
    parts=0
    excessive_parts=`echo $vip | sed -e "s/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*//"`
    if [ "$excessive_parts" ]; then
	ip_fail=true
    else
	for iptok in `echo $vip | sed 's/\./ /g'`
	do
	    expr $iptok + 1 >/dev/null 2>&1 || {
		ip_fail=true
		break
	    }
	    [ $iptok -gt 255 ] && {
		ip_fail=true
		break
	    }
	    parts=`expr $parts + 1`
	done
    fi
    [ $parts -eq 4 ] || ip_fail=true
    [ "$ip_fail" = "false" ] && return 0

    echo "Error: $vip does not appear to be a valid ipv4 style address."
    echo "Please enter this value again."
    return 1
}

valid_netmask()
{
    valid_netmask_value $1 || return 1
    INPUT_NETMASK=$1
    ZERO_FOUND=0

    for TOK in `echo $INPUT_NETMASK | sed 's/\./ /g'`
    do
        if [ "$ZERO_FOUND" = 1 ]; then
            if [ "$TOK" != 0 ]; then
                echo "Error: Netmask must contain zero, not $TOK, at this position."
                echo "Please enter this value again."
                return 1
            fi
        else
            OKAY=0
            for VALID_MASK in 0 128 192 224 240 248 252 254 255
            do
                if [ "$TOK" = "$VALID_MASK" ]; then
                    if [ "$TOK" != 255 ]; then
                        ZERO_FOUND=1
                    fi
                    OKAY=1
                    break;
                fi
            done
            if [ "$OKAY" = 0 ]; then
                echo "Error: $TOK is not a valid netmask value."
                echo "Please enter this value again."
                return 1
            fi
        fi
    done
    return 0
}

valid_gw()
{
    valid_ip $1 || return 1
    INPUT_GW=$1
    INPUT_IP=$2
    INPUT_MASK=$3
    GW=0
    IP=0
    MASK=0

    for TOK in `echo $INPUT_GW | sed 's/\./ /g'`
    do
        GW=$(($GW * 256 + $TOK))
    done
    for TOK in `echo $INPUT_IP | sed 's/\./ /g'`
    do
        IP=$(($IP * 256 + $TOK))
    done
    for TOK in `echo $INPUT_MASK | sed 's/\./ /g'`
    do
        MASK=$(($MASK * 256 + $TOK))
    done
    if [ $((($GW & $MASK) == ($IP & $MASK))) != 1 ]; then
        echo "Error: Gateway $INPUT_GW and IP address $INPUT_IP not in same subnet."
        echo "Please enter this value again."
        return 1
    fi
    return 0
}

copy_setup()
{
    cp $TARGET_IFCG* /etc/sysconfig/network-scripts/
}

set_dhcp()
{
    echo "DEVICE=${REAL_IF}" > $ethfile
    echo "ONBOOT=yes" >> $ethfile
    echo "BOOTPROTO=dhcp" >> $ethfile

    copy_setup
}

set_ip()
{
    echo
    echo "Please enter the IP configuration for this machine."
    echo "Each item should be entered as an IP version 4 style address in dotted-decimal"
        echo "notation (for example, 10.20.30.40)"
    echo

    ip=
    netmask=
    defaultgw=
    while true
    do
        prompt "Enter IP address" 
        if [ $? -eq 0 ]; then
            return 0
        fi
        ip=$INPUT
        valid_ip $ip || continue
        promptyn "Is $ip correct" || continue
        break
    done
    echo
    while true
    do
        prompt "Enter netmask"
        if [ $? -eq 0 ]; then
            return 0
        fi
        netmask=$INPUT
        valid_netmask $netmask || continue
        promptyn "Is $netmask correct" || continue
        break
    done
    echo
    while true
    do
        prompt "Enter default gateway (IP)"
        if [ $? -eq 0 ]; then
            return 0
        fi
        defaultgw=$INPUT
        valid_gw $defaultgw $ip $netmask || continue
        promptyn "Is $defaultgw correct" || continue
        break
    done

    BROADCAST=`ipcalc -b $ip $netmask 2>/dev/null | cut -d= -f 2`

    echo "DEVICE=${REAL_IF}" > $ethfile
    echo "ONBOOT=yes" >> $ethfile
    echo "BOOTPROTO=static" >> $ethfile
    echo "IPADDR=$ip" >> $ethfile
    echo "NETMASK=$netmask" >> $ethfile
    echo "GATEWAY=$defaultgw" >> $ethfile
    echo "BROADCAST=$BROADCAST" >> $ethfile

    copy_setup

    return 1
}

echo
echo "This flash recovery utility will restore a corrupted root flash"
echo "partition with a factory default image, which will be copied from"
echo "an ssh server. This process will take several minutes and will"
echo "overwrite the contents of the root partition."
echo 
echo "You can exit and restart the recovery process at any time by"
echo "pressing CTRL-C."
echo 

ALLCORRECT=

while [ -z $ALLCORRECT ]; do 
    
    NETWORK_UP=
    STATIC_IP=`cat /etc/sysconfig/network-scripts/ifcfg-$FIRST_IF | grep static`

    IPADDR=`ifconfig $FIRST_IF | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`    
    if [ -z $IPADDR ]; then
        IPADDR="0.0.0.0"
    fi
    MASK=`ifconfig  | grep 'Mask:'| grep -v '127.0.0.1' | cut -d: -f4 | awk '{ print $1}'`
    if [ -z $MASK ]; then
        MASK="0.0.0.0"
    fi
    
    echo "First, the network must be configured. If you are connected to a DHCP server"
    echo "you may already have a valid IP address and do not need to do anything."
    echo -n "Your current IP address is: $IPADDR, netmask $MASK "
    if [ -z $STATIC_IP ]; then
        echo "(DHCP assigned)."
    else
        echo "(Statically assigned)."
    fi
    
    while [ -z $NETWORK_UP ]; do
        
        echo 
        echo "Select on the of the following options:"
        echo
        echo "1. Proceed with this setting"
        echo "2. Use DHCP to get an IP address"
        echo "3. Assign a static IP address"
        echo
        
        prompt_number
        RESP=$?
        
        if [ $RESP = "1" ]; then
            NETWORK_UP=true
        elif [ $RESP = "2" ]; then
            echo "Restarting network with DHCP."
            ifdown $FIRST_IF
            set_dhcp
            ifup $FIRST_IF
            if [ $? -eq 0 ]; then
                NETWORK_UP=true
                IPADDR=`ifconfig $FIRST_IF | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`    
                echo "Your DHCP assigned address is $IPADDR"
            else
                echo "Failed to get IP address."
            fi
        elif [ $RESP = "3" ]; then
            ifdown $FIRST_IF
            set_ip
            if [ $? -eq 0 ]; then
                continue
            fi
            
            ifup $FIRST_IF 2>&1 >/dev/null
            if [ $? -eq 0 ]; then
                NETWORK_UP=true
            else
                echo "Network could not be started."
            fi
        else
            echo 
            echo "That is not a valid selection."
            echo
        fi
        
    done

    cd /tmp
    # Clear out any old image
    rm -Rf /tmp/*
    
    echo
    echo "You will now be placed in an FTP client. After you log in,"
    echo "you can use the following commands:"
    echo
    echo "  ls               List directory"
    echo "  cd               Change directory"
    echo "  mget <filename>  Download recovery image called <filename>"
    echo 
    echo "Type \"quit\" when the FTP download is complete."
    echo
    
    while true
      do
      prompt "Enter FTP server IP address" 
      ftp_ip=$INPUT
      valid_ip $ftp_ip || continue
      promptyn "Is $ftp_ip correct" || continue
      break
    done
    
    ftp $ftp_ip

    IMGBASENAME=`ls /tmp/*.gz` 
    
    echo "Uncompressing image..."
    gunzip -t $IMGBASENAME
    if [ $? -ne 0 ]; then
        echo "An error occurred. Image was not downloaded correctly. Please try again."
    else
        echo "Recovery image was downloaded and uncompressed successfully." 
        ALLCORRECT=y
    fi
    
done

echo "Writing root partition..."
gunzip -c $IMGBASENAME | dd of=$ROOT_PARTITION bs=1M >/dev/null
if [ $? -ne 0 ]; then
    echo "dd failed.Image has not been restored."
    control_c
fi

# The block below is a placeholder until mount corruption issue is resolved. 

#echo "Root image successfully restored."
#echo "Restoring user configuration from backup..."

#/opt/meru/bin/restore_from_data_partition
#if [ $? -ne 0 ]; then
#    echo "Although configuration has not been successfully restored from backup,"
#    echo "the root image is restored and functional. You can either run this utility"
#    echo "again to try to restore the configuration for backup or exit and reboot."
#    echo "If you exit now, you will have to configure the system again when it boots."
#    echo

#    while true
#      do
#      promptyn "Do you want to reboot now"
#      if [ $? -eq 0 ]; then
#          control_c
#      elif [ $? -eq 1 ]; then
#          reboot
#      else
#          echo "That is not a valid response."
#      fi
#    done
#fi

echo "Image successfully restored. Rebooting system. "

reboot
