#!/bin/ash
#
# compute_file_diffs:
# This script computes the list of files that have been added, removed or changed
# between the old and the new versions.
# It computes file diffs for both regular files and symlinks.
#
# Usage: compute_file_diffs <dest_partition> <install_type>
#        <dest_partition> = partition in which fw is going to be installed
#                           can be "primary" or "backup"
#        <install_type>   = eth (for ethernet based update) or sp (via ONTAP)
# 
# If <dest_partition> = primary, the differences are computed between the new 
#                       FW package and the primary partition.
# If <dest_partition> = backup, the differences are computed between the primary
#                       and the backup partitions.
# 
# Kiran Kamity, 09/24/2004
#
# Return Values:
#     101 = Invalid arguments
#     102 = Metadata info not present in new package
#     103 = Metadata Info not present in primary
#     104 = Metadata Info not present in backup
#     105 = Miscellaneous Error
#

ETH_FW_PACKAGE_DIR=/tmp/fud_eth/RLM_FW
SP_FW_PACKAGE_DIR=/tmp/ORFTP/fud_sp

PRIMARY_REGFILES=/etc/rlm_install/primary/checksum.regfiles
BACKUP_REGFILES=/etc/rlm_install/backup/checksum.regfiles

PRIMARY_SYMLINKS=/etc/rlm_install/primary/info.symlinks
BACKUP_SYMLINKS=/etc/rlm_install/backup/info.symlinks

# Compute regular files that have been added, changed or deleted

#
# Regfile_diffs: 
# Computes the regular file diffs necessary for differential file based update
# Args:
#     $1 = New regfiles
#     $2 = Current regfiles
#     $3 = Output file containing Regfiles added/changed
#     $4 = Output file containing Regfiles deleted
#
Regfile_diffs () {
# echo "Regfile_diffs $1 $2 $3 $4";
   
# Compute added and changed files

    diff $1 $2 | grep -q "<";
    if [ $? = 0  ] ; then
	DIFFS=`diff $1 $2 | grep "<"`;
	for word in $DIFFS; do
	    echo $word | grep -q "/";
	    if [ $? = 0 ] ; then
		echo $word >> $3;
	    fi
	done
    fi
    
    
# Compute deleted files

    diff $1 $2 | grep -q ">";
    if [ $? = 0 ] ; then
	DIFFS=`diff $1 $2 | grep ">"`;
	for word in $DIFFS; do
	    echo $word | grep -q "/";
	    if [ $? = 0 ] ; then
		grep -q $word $3;
		if ! [ $? = 0 ] ; then
		    echo $word >> $4;
		fi
	    fi
	done
    fi
 }

# Compute added, changed and deleted symlinks

#
# Symlink_diffs: 
# Computes the symlink diffs necessary for differential file based update
# Args:
#     $1 = New symlinks
#     $2 = Current symlinks
#     $3 = Output file containing symlinks added/changed
#     $4 = Output file containing symlinks deleted
#
Symlink_diffs () {
# echo "Symlink_diffs $1 $2 $3 $4";

# Compute added and changed symlinks

    diff $1 $2 | grep -q "<";
    if [ $? = 0  ] ; then
	diff $1 $2 | grep "<" | sed 's/< //g' >> $3;
    fi
    
    
# Compute deleted symlinks

    diff $1 $2 | grep -q ">";
    if [ $? = 0 ] ; then
	DIFFS=`diff $1 $2 | grep ">" | sed 's/>//g'`;
	COUNT=0;
	for word in $DIFFS; do
	    if [ $(($COUNT%2)) -eq 0 ]; then
		grep -q $word $3;
		if ! [ $? = 0 ] ; then
		    echo $word >> $4;
		fi
	    fi
	    COUNT=$(($COUNT + 1));
	done
    fi
}


# ...Program execution starts here...

# Verify command line arguments
if ! [ $# -eq 2 ] ; then
	echo "Usage: compute_file_diffs <dest_partition> <install_type>";
	exit 101;
fi

if [ $2 = "eth" ] ; then
    NEW_PACKAGE_REGFILES=$ETH_FW_PACKAGE_DIR/install/checksum.regfiles
    NEW_PACKAGE_SYMLINKS=$ETH_FW_PACKAGE_DIR/install/info.symlinks
    DIFFS_DIR=$ETH_FW_PACKAGE_DIR/differences
    
    PRIMARY_REGFILES_ADD=$DIFFS_DIR/add.regfiles.primary
    PRIMARY_REGFILES_DEL=$DIFFS_DIR/del.regfiles.primary
    PRIMARY_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.primary
    PRIMARY_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.primary

    BACKUP_REGFILES_ADD=$DIFFS_DIR/add.regfiles.backup
    BACKUP_REGFILES_DEL=$DIFFS_DIR/del.regfiles.backup
    BACKUP_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.backup
    BACKUP_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.backup

elif [ $2 = "sp" ] ; then
    NEW_PACKAGE_REGFILES=$SP_FW_PACKAGE_DIR/install/checksum.regfiles
    NEW_PACKAGE_SYMLINKS=$SP_FW_PACKAGE_DIR/install/info.symlinks
    DIFFS_DIR=$SP_FW_PACKAGE_DIR/differences

    PRIMARY_REGFILES_ADD=$DIFFS_DIR/add.regfiles.primary
    PRIMARY_REGFILES_DEL=$DIFFS_DIR/del.regfiles.primary
    PRIMARY_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.primary
    PRIMARY_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.primary

    BACKUP_REGFILES_ADD=$DIFFS_DIR/add.regfiles.backup
    BACKUP_REGFILES_DEL=$DIFFS_DIR/del.regfiles.backup
    BACKUP_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.backup
    BACKUP_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.backup
else
    echo "Usage: compute_file_diffs <dest_partition> <install_type>";
    exit 101;
fi

# Compute primary-to-backup root-fs file changes
# Determine which files/symlinks have been removed, added or changed

# compute_file_diffs between new package and primary
if [ $1 = "primary" ] ; then
#    echo "primary";

    mkdir -p $DIFFS_DIR;
    rm -f $PRIMARY_REGFILES_ADD;
    rm -f $PRIMARY_REGFILES_DEL;
    rm -f $PRIMARY_SYMLINKS_ADD;
    rm -f $PRIMARY_SYMLINKS_DEL;
    

    if ! [ -f $NEW_PACKAGE_REGFILES -a \
	-f $NEW_PACKAGE_SYMLINKS ] ; then
	
	echo "ERROR: Metadata absent in new package";
	exit 102;
	
    elif ! [ -f $PRIMARY_REGFILES -a \
	-f $PRIMARY_SYMLINKS ] ; then
	
	echo "ERROR: No Metadata Information in primary";
	exit 103;

    else
	Regfile_diffs $NEW_PACKAGE_REGFILES $PRIMARY_REGFILES $PRIMARY_REGFILES_ADD $PRIMARY_REGFILES_DEL;
	Symlink_diffs $NEW_PACKAGE_SYMLINKS $PRIMARY_SYMLINKS $PRIMARY_SYMLINKS_ADD $PRIMARY_SYMLINKS_DEL;
    fi

# compute_file_diffs between primary and backup
elif [ $1 = "backup" ] ; then
#    echo "backup";

    mkdir -p $DIFFS_DIR;
    rm -f $BACKUP_REGFILES_ADD;
    rm -f $BACKUP_REGFILES_DEL;
    rm -f $BACKUP_SYMLINKS_ADD;
    rm -f $BACKUP_SYMLINKS_DEL;

    if ! [ -f $PRIMARY_REGFILES -a \
	-f $PRIMARY_SYMLINKS ] ; then

	echo "ERROR: No metadata information in primary";
	exit 103;

    elif ! [ -f $BACKUP_REGFILES -a \
	-f $BACKUP_SYMLINKS ] ; then
	
	echo "ERROR: No Metadata Information in backup";
	exit 104;

    else
	Regfile_diffs $PRIMARY_REGFILES $BACKUP_REGFILES $BACKUP_REGFILES_ADD $BACKUP_REGFILES_DEL;
	Symlink_diffs $PRIMARY_SYMLINKS $BACKUP_SYMLINKS $BACKUP_SYMLINKS_ADD $BACKUP_SYMLINKS_DEL;
    fi
else
    echo "Usage: compute_file_diffs <dest_partition> <install_type>";
    exit 101;
fi
