#!/bin/sh
###############################################################################
## syncconfig                                                                 #
###############################################################################
## Copyright 2002. Spinnaker Networks Inc.                                    #
## All rights reserved.                                                       #
##                                                                            #
###############################################################################
## This script is synchronize the configuration on '/altroot' directory       #
## with that on the '/' directory                                             #
###############################################################################

#########
## List of files that need to be synchronized 
## (/var/spinmgmt is automatically done, hence should not be specified here)
## 
#########
# OTHER_FILES_TO_SYNC="
#	 /etc/passwd
#        /etc/sysconfig/network-scripts (would copy the whole directory)
#          "
#########
OTHER_FILES_TO_SYNC="
        /etc/passwd
        /etc/sysconfig/network-scripts/ifcfg-eth0
        /etc/sysconfig/network-scripts/ifcfg-eth1
        /etc/sysconfig/network-scripts/ifcfg-eth2
        /etc/sysconfig/network-scripts/ifcfg-eth3
        /etc/sysconfig/network-scripts/ifcfg-eth4
        /etc/sysconfig/network-scripts/ifcfg-eth5
         "

#########
## Function: Usage
## Displays the Usage for this script
#########
Usage ()
{
    echo "usage:  syncconfig [-c] [-f] [-h]"
    echo "            c:  (optional) if specified, synchronizes the configuration on '/' with that on '/altroot'"
    echo "                if not specified, synchronizes the configuration on '/altroot' with that on '/'"
    echo "            f:  (optional) does a force synchronization (does not validate version information)"
    echo "            h:  displays this usage message"
}

#########
## Function: LogInfo & LogCritical
## Send a Info/Critical message to system logger
#########
LogInfo ()
{
    echo $*
    logger -p daemon.info -t SyncConfig -- $*
}

LogCritical ()
{
    echo $* >&2
    logger -p daemon.crit -t SyncConfig -- $*
}


#########
## Function: QuitOnError
## Displays given error message and exits the script
#########
QuitOnError ()
{
    LogCritical $*
    LogCritical "syncconfig --- Stopped due to error ---"
    exit 1
}


#########
## Function: Interrupted
## Called when the script is interrupted
#########
trap 'Interrupted' INT QUIT TERM

Interrupted ()
{
    QuitOnError "syncconfig --- Interrupted ---"
    exit 1
}

#########
## Function: GetSoftwareInfoFromFile
## Reads the software info file specfied ($1) and updates the following variables
##     T_MAJOR
##     T_MINOR
##     T_PATCH
##     T_BUILDNUMBER
#########
GetSoftwareInfoFromFile ()
{
    T_SW_FILE=$1

    if [ ! -f ${T_SW_FILE} ]; then
	QuitOnError "Software Info file ${T_SW_FILE} Does not Exist" >&2
    fi

    T_MAJOR=`cat ${T_SW_FILE} | grep "MAJOR=" | sed 's/MAJOR=//'`
    T_MINOR=`cat ${T_SW_FILE} | grep "MINOR=" | sed 's/MINOR=//'`
    T_PATCH=`cat ${T_SW_FILE} | grep "PATCH=" | sed 's/PATCH=//'`
    T_BUILDNUMBER=`cat ${T_SW_FILE} | grep "BUILDNUMBER=" | sed 's/BUILDNUMBER=//'`
}


#########
## Function: ParseSoftwareInfo
## Parse the given version information in T_VERSION and updates the following variables
##     T_MAJOR
##     T_MINOR
##     T_PATCH
##     T_BUILDNUMBER
#########
ParseSoftwareInfo ()
{
    T_MAJOR=`echo ${T_VERSION} | grep "MAJOR=" | sed 's/\(.*MAJOR=\{1\}\)\([0-9]\+\).*/\2/'`
    T_MINOR=`echo ${T_VERSION} | grep "MINOR=" | sed 's/\(.*MINOR=\{1\}\)\([0-9]\+\).*/\2/'`
    T_PATCH=`echo ${T_VERSION} | grep "PATCH=" | sed 's/\(.*PATCH=\{1\}\)\([0-9]\+\).*/\2/'`
    T_BUILDNUMBER=`echo ${T_VERSION} | grep "BUILDNUMBER=" | sed 's/\(.*BUILDNUMBER=\{1\}\)\([0-9]\+\).*/\2/'`
}


#########
## Function: GetSoftwareInfo
## Reads the software info file specfied ($1) and updates the following variables
##     T_MAJOR
##     T_MINOR
##     T_PATCH
##     T_BUILDNUMBER
#########
GetSoftwareInfo ()
{
    T_SW_FILE=$1

    if [ -f ${T_SW_FILE} ]
    then
	GetSoftwareInfoFromFile ${T_SW_FILE}
    else

	IS_ALTROOT=`echo ${T_SW_FILE} | grep "^/altroot"`
	if [ ! -z ${IS_ALTROOT} ]
	then
	    CHANGE_ROOT="--root /altroot"
	else
	    CHANGE_ROOT=
	fi

	T_VERSION=`rpm ${CHANGE_ROOT} -q spinmgmt --queryformat "VERSION=%-18{VERSION} BUILDNUMBER=%7{RELEASE}" | sed 's/\(VERSION=\{1\}\)\([0-9]\+\)\(.\([0-9]\+\)\)\?\(.\([0-9]\+\)\)\?/ MAJOR=\2 MINOR=\4 PATCH=\6/'`

	ParseSoftwareInfo
    fi
}


#########
## Function: getParentPid
## Returns the parent PID
#########
getParentPid() {
    echo `/sbin/pidof -x $1 | sed -e 's/ /\\
/g' | sort -n | sed -e '1q'`
    return $?;
}

#########
## Move the device files
#########
MoveDeviceFile ()
{
    OLD_DEVICE=$1
    NEW_DEVICE=$2

    if [ -f ${DESTINATION}/etc/sysconfig/network-scripts/ifcfg-${NEW_DEVICE} ]; then
	rm -rf ${DESTINATION}/etc/sysconfig/network-scripts/ifcfg-${NEW_DEVICE}
    fi

    if [ -f ${SOURCE}/etc/sysconfig/network-scripts/ifcfg-${OLD_DEVICE} ]; then
	cat ${SOURCE}/etc/sysconfig/network-scripts/ifcfg-${OLD_DEVICE} | sed "s/${OLD_DEVICE}/${NEW_DEVICE}/" >  ${DESTINATION}/etc/sysconfig/network-scripts/ifcfg-${NEW_DEVICE}
    fi 
}

#########
## Retrieve the Command Line Options
#########

SYNC_CURRENT=0
FORCE=0
GETOPTS="getopts 'cfh' OPTION $*"

${GETOPTS}
RET=$?
while [ ${RET}  -le 0 ]
do
  case ${OPTION} in
      c)  SYNC_CURRENT=1
	  ;;
      f)  FORCE=1
	  ;;
      h)  Usage
	  exit 0
	  ;;
      *)  Usage
	  exit 1
	  ;;
  esac

  ${GETOPTS}
  RET=$?
done

LogInfo "syncconfig --- BEGIN ---"

######
## Initialize source & destination
######
if [ ${SYNC_CURRENT} -eq 0 ]; then
    SOURCE="/"
    DESTINATION="/altroot"
else
    SOURCE="/altroot"
    DESTINATION="/"
fi

LogInfo "Sync Configuration from ${SOURCE} to ${DESTINATION} with Force=${FORCE}"

#########
## Make sure hamgr, vldb and spinmgmt are not running
#########
if [ -f /sbin/hamgr ]; then
    /sbin/hamgr -status >/dev/null 2>&1
    RET=$?
    if [ ${RET} -eq 0 ]; then
	QuitOnError "Cannot Perform SyncConfig when hamgr is running" 
    fi
fi

if [ -f /etc/init.d/spinvldb ]; then
    /etc/init.d/spinvldb status >/dev/null 2>&1
    RET=$?
    if [ ${RET} -eq 0 ]; then
	QuitOnError "Cannot Perform SyncConfig when vldb is running" 
    fi
fi

PID=`getParentPid "Tomcat"`;
RET=$?
if [ $RET -eq 0 -a -n "$PID" ]; then
    QuitOnError "Cannot Perform SyncConfig when spinmgmt is running" 
fi



#########
## Get the software version of the current RootFileSystem
#########
SW_FILE="/etc/sysconfig/spinsoftware"
GetSoftwareInfo ${SW_FILE}
CUR_MAJOR=${T_MAJOR}
CUR_MINOR=${T_MINOR}
CUR_PATCH=${T_PATCH}
CUR_BUILDNUMBER=${T_BUILDNUMBER}
export CUR_MAJOR CUR_MINOR CUR_PATCH CUR_BUILDNUMBER

LogInfo "The Version information of the current RootFileSystem"
LogInfo "    CUR_MAJOR=${CUR_MAJOR}"
LogInfo "    CUR_MINOR=${CUR_MINOR}"
LogInfo "    CUR_PATCH=${CUR_PATCH}"
LogInfo "    CUR_BUILDNUMBER=${CUR_BUILDNUMBER}"


#########
## Get the software version of the alternate RootFileSystem
#########
ALT_SW_FILE="/altroot/etc/sysconfig/spinsoftware"
GetSoftwareInfo ${ALT_SW_FILE}
ALT_CUR_MAJOR=${T_MAJOR}
ALT_CUR_MINOR=${T_MINOR}
ALT_CUR_PATCH=${T_PATCH}
ALT_CUR_BUILDNUMBER=${T_BUILDNUMBER}
export ALT_CUR_MAJOR ALT_CUR_MINOR ALT_CUR_PATCH ALT_CUR_BUILDNUMBER

LogInfo "The Version information of the alternate RootFileSystem"
LogInfo "    ALT_CUR_MAJOR=${ALT_CUR_MAJOR}"
LogInfo "    ALT_CUR_MINOR=${ALT_CUR_MINOR}"
LogInfo "    ALT_CUR_PATCH=${ALT_CUR_PATCH}"
LogInfo "    ALT_CUR_BUILDNUMBER=${ALT_CUR_BUILDNUMBER}"

######
## NOTE: Add checks to verify version information and validate
##       whether syncconfig should proceed for the given version numbers on
##       the /  and  /altroot  partitions
######
## (e.g.) To Not allow syncconfig from a higher version number
######
if [ ${FORCE} -eq 0 ]; then
    invalid=0
    if [ ${SYNC_CURRENT} -eq 1 ]; then
	if [ ${ALT_CUR_MAJOR} -gt ${CUR_MAJOR} ]; then
	    invalid=1
	elif [ ${ALT_CUR_MAJOR} -eq ${CUR_MAJOR} ]; then
	    if [ ${ALT_CUR_MINOR} -gt ${CUR_MINOR} ]; then
		invalid=1
	    elif [ ${ALT_CUR_MINOR} -eq ${CUR_MINOR} ]; then
		if [ ${ALT_CUR_PATCH} -gt ${CUR_PATCH} ]; then
		    invalid=1
		elif [ ${ALT_CUR_PATCH} -eq ${CUR_PATCH} ]; then
		    if [ ${ALT_CUR_BUILDNUMBER} -gt ${CUR_BUILDNUMBER} ]; then
			invalid=1
		    fi
		fi
	    fi
	fi
    else
	if [ ${CUR_MAJOR} -gt ${ALT_CUR_MAJOR} ]; then
	    invalid=1
	elif [ ${CUR_MAJOR} -eq ${ALT_CUR_MAJOR} ]; then
	    if [ ${CUR_MINOR} -gt ${ALT_CUR_MINOR} ]; then
		invalid=1
	    elif [ ${CUR_MINOR} -eq ${ALT_CUR_MINOR} ]; then
		if [ ${CUR_PATCH} -gt ${ALT_CUR_PATCH} ]; then
		    invalid=1
		elif [ ${CUR_PATCH} -eq ${ALT_CUR_PATCH} ]; then
		    if [ ${CUR_BUILDNUMBER} -gt ${ALT_CUR_BUILDNUMBER} ]; then
			invalid=1
		    fi
		fi
	    fi
	fi
    fi

    if [ ${invalid} -eq 1 ]; then
	QuitOnError "Cannot syncconfig for given software versions" >&2
    fi   
fi



#########
## Find the Spinserver Product ID and Model Number
#########
SPINSERVER_PRODUCT_ID=`cat /proc/smbios/base_board-0-0002 | grep "Product:" | sed 's/.*Product: *//'`
SPINSERVER_MODEL="S3300"
if [ ${SPINSERVER_PRODUCT_ID} == "X5DL8" ]; then
    SPINSERVER_MODEL="S4100"
fi

LogInfo "SPINSERVER_MODEL=${SPINSERVER_MODEL}"

######
## Clean the configuration on the destination file system
######
LogInfo "Cleaning the configuration on the destination file system"

if [ -d ${DESTINATION}/var/spinmgmt/nvram ]; then
    rm -rf ${DESTINATION}/var/spinmgmt/nvram.old ${DESTINATION}/var/spinmgmt/nvram.old.tgz
    mv -f ${DESTINATION}/var/spinmgmt/nvram ${DESTINATION}/var/spinmgmt/nvram.old
    (cd ${DESTINATION}/var/spinmgmt/nvram.old; tar -czf ${DESTINATION}/var/spinmgmt/nvram.old.tgz .)
    rm -rf ${DESTINATION}/var/spinmgmt/nvram.old
fi

if [ -d ${DESTINATION}/var/spinmgmt/rdb ]; then
    rm -rf ${DESTINATION}/var/spinmgmt/rdb.old ${DESTINATION}/var/spinmgmt/rdb.old.tgz
    mv -f ${DESTINATION}/var/spinmgmt/rdb ${DESTINATION}/var/spinmgmt/rdb.old
    (cd ${DESTINATION}/var/spinmgmt/rdb.old; tar -czf ${DESTINATION}/var/spinmgmt/rdb.old.tgz .)
    rm -rf ${DESTINATION}/var/spinmgmt/rdb.old
fi

if [ -d ${DESTINATION}/var/spinmgmt/log ]; then
    rm -rf ${DESTINATION}/var/spinmgmt/log.old ${DESTINATION}/var/spinmgmt/log.old.tgz
    mkdir ${DESTINATION}/var/spinmgmt/log.old
    cp -Rp ${DESTINATION}/var/spinmgmt/log/local_spin_audit.log* ${DESTINATION}/var/spinmgmt/log.old/.
    (cd ${DESTINATION}/var/spinmgmt/log.old; tar -czf ${DESTINATION}/var/spinmgmt/log.old.tgz .)
    rm -rf ${DESTINATION}/var/spinmgmt/log ${DESTINATION}/var/spinmgmt/log.old
fi

sync; sync; sync


######
## Copy the configuration from the source to destination file system
######
LogInfo "Copying the configuration from the source to destination file system"

mkdir -p ${DESTINATION}/var/spinmgmt/nvram.new
mkdir -p ${DESTINATION}/var/spinmgmt/rdb.new
mkdir -p ${DESTINATION}/var/spinmgmt/log.new

cp -Rp ${SOURCE}/var/spinmgmt/nvram/. ${DESTINATION}/var/spinmgmt/nvram.new/.
cp -Rp ${SOURCE}/var/spinmgmt/rdb/. ${DESTINATION}/var/spinmgmt/rdb.new/.
cp -Rp ${SOURCE}/var/spinmgmt/log/local_spin_audit.log* ${DESTINATION}/var/spinmgmt/log.new/.
if [ -d ${SOURCE}/var/spinmgmt/keys ]; then

    if [ -d ${DESTINATION}/var/spinmgmt/keys ]; then
	rm -rf ${DESTINATION}/var/spinmgmt/keys.old
	mv -f ${DESTINATION}/var/spinmgmt/keys ${DESTINATION}/var/spinmgmt/keys.old
    fi

    mkdir -p ${DESTINATION}/var/spinmgmt/keys.new
    cp -Rp ${SOURCE}/var/spinmgmt/keys/. ${DESTINATION}/var/spinmgmt/keys.new/.
fi

sync; sync; sync

mv -f ${DESTINATION}/var/spinmgmt/nvram.new ${DESTINATION}/var/spinmgmt/nvram
mv -f ${DESTINATION}/var/spinmgmt/rdb.new ${DESTINATION}/var/spinmgmt/rdb
mv -f ${DESTINATION}/var/spinmgmt/log.new ${DESTINATION}/var/spinmgmt/log
if [ -d ${DESTINATION}/var/spinmgmt/keys.new ]; then
    mv -f ${DESTINATION}/var/spinmgmt/keys.new ${DESTINATION}/var/spinmgmt/keys
fi

sync; sync; sync

######
## Copy the files in the OTHER_FILES_TO_SYNC list to DESTINATION
######
LogInfo "Copying the files in the OTHER_FILES_TO_SYNC list to DESTINATION"

for OTHER_FILE in $OTHER_FILES_TO_SYNC
do
     if [ -a ${SOURCE}/${OTHER_FILE} ]; then
	 rm -rf ${DESTINATION}/${OTHER_FILE}
	 if [ -d ${SOURCE}/${OTHER_FILE} ]; then
	     mkdir -p ${DESTINATION}/${OTHER_FILE}
	     cp -Rp ${SOURCE}/${OTHER_FILE}/. ${DESTINATION}/${OTHER_FILE}/.
	 else
	     cp -p ${SOURCE}/${OTHER_FILE} ${DESTINATION}/${OTHER_FILE}
	 fi
     fi
done

#########
## If SpinServer 4100 and if eth0 is e1000, then need to move the device files
## 
#########
if [ ${SPINSERVER_MODEL} == "S4100" ]; then
    CURRENT_ETH0_ALIAS=`cat ${SOURCE}/etc/modules.conf |  sed 's/#.*//' | grep "alias eth0" | sed 's/alias eth0 //'`
    if [ ${CURRENT_ETH0_ALIAS} == "e1000" ]; then

	LogInfo "SpinServer is 4100 and eth0 is e1000; moving the device files and updating modules.conf"

	cat ${SOURCE}/etc/modules.conf | sed 's/.*alias eth0 .*/alias eth0 bcm5700/' > ${DESTINATION}/etc/modules.conf

	if [ -f ${SOURCE}/etc/sysconfig/network-scripts/ifcfg-eth0 ]; then
	    cp -p ${SOURCE}/etc/sysconfig/network-scripts/ifcfg-eth0 ${DESTINATION}/etc/sysconfig/network-scripts/ifcfg-eth0	
	fi

	MoveDeviceFile eth2 eth1
	MoveDeviceFile eth3 eth2
	MoveDeviceFile eth4 eth3
	MoveDeviceFile eth5 eth4

	sync;sync;sync;

	if [ ${DESTINATION} == "/" ]; then
	    cp /etc/sysconfig/ipchains /tmp/ipchains.b4.syncconfig
	    modprobe bcm5700
	    /sbin/fix_chains
	    cp /etc/sysconfig/ipchains /tmp/ipchains.after.syncconfig
	else
	    rm -f /tmp/rc.update

	    if [ -f /altroot/etc/rc.update ]; then
		cat /altroot/etc/rc.update | sed 's/.*modprobe bcm5700.*//' | sed 's/.*fix_chains.*//' > /tmp/rc.update
	    fi

	    echo "" >> /tmp/rc.update
	    echo "modprobe bcm5700" >> /tmp/rc.update
	    echo "/sbin/fix_chains" >> /tmp/rc.update
	    echo "" >> /tmp/rc.update

	    cat /tmp/rc.update > /altroot/etc/rc.update
	    sync;sync;sync;
	fi
    fi
fi

sync; sync; sync

#########
## Update the sync time  information on the destination RootFileSystem 
#########
LogInfo "Updating the sync time  information on the destination RootFileSystem"

SW_FILE="${DESTINATION}/etc/sysconfig/spinsoftware"
TMP_FILE="/tmp/spinsoftware.tmp"
CFG_SYNCTIME=`date +"%a %b %d %T %Y"`
cat ${SW_FILE} | sed '/.*LAST_CFG_SYNCTIME=.*/d' > ${TMP_FILE}
echo "LAST_CFG_SYNCTIME=${CFG_SYNCTIME}" >> ${TMP_FILE}
mv ${TMP_FILE} ${SW_FILE} 

#############
## let the firewall provider know that an upgrade was just performed.
#############
LogInfo "Creating the /etc/spin.firewall.upgrade file"
touch /etc/spin.firewall.upgrade

sync; sync; sync

######
## syncconfig is complete!!!
######
LogInfo "syncconfig --- END ---"
exit 0
