#!/bin/bash
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html

#-------------------------------------------------------------------------------
#=head1  otherpkgs  - only runs on Linux
#=head2  It gets the extra rpms and install/update them.
#        The environment variable OTHERPKGS contains the rpms to be installed/updated.
#        On MN, You need to:
#        1. put rpms under /install/post/otherpkgs/os/arch directory where 'os' and 'arch'
#           can be found in the nodetype table.
#        2. put the name of the packages to /opt/xcat/share/xcat/netboot(install)/platform
#           directory. The file name is one of the following:
#              profile.os.arch.otherpkgs.pkglist  
#              profile.os.otherpkgs.pkglist   
#              profile.arch.otherpkgs.pkglist  
#              profile.otherpkgs.pkglist
#   The install/deployment process will pick up the rpms and install them on the nodes. 
#   However, if the nodes have already installed and up and running, you can run the following
#   command to have the extra rpms installed:
#       updatenode noderange otherpkgs 
#   
#=cut
#-------------------------------------------------------------------------------

# pmatch determines if 1st argument string is matched by 2nd argument pattern

pmatch ()
{
  case $1 in
    $2) return 0;;  # zero return code means string matched by pattern
  esac

  return 1          # non-zero return code means string not matched by pattern
}

##
##  The following routines implement the notion of an array.
##  The POSIX shell does not support arrays.
##  With these routines, an array conceptually called "my_array" is implmented using the following series
##  of variables:
##
##      my_array__ARRAY_HIGH_INDEX  - holds the highest index used in the array
##      my_array__0   - value for element 0 of my_array: my_array[0] in standard array notation
##      my_array__1   - value for element 1 of my_array: my_array[1] in standard array notation
##         .                             .
##         .                             .
##         .                             .
##

#
#  array_empty - make the array whose name is given by $1 empty (with no elements).
#
#    sample call:  array_empty my_array
#

array_empty ()
{
    local array_name="$1"
    local high_ndx_varname="${array_name}__ARRAY_HIGH_INDEX"
    local elem_varname
    local high_ndx
    local ndx

    # Determine current element count

    eval "high_ndx=\$${high_ndx_varname}"

    if [ -z "$high_ndx" ]; then
        return
    fi

    # Unset all previously defined element variables and the high index variable

    ndx=0

    while [ $ndx -le $high_ndx ]; do
        elem_varname="${array_name}__${ndx}"

        eval "unset ${elem_varname}"

        ndx=$(expr $ndx + 1)
    done

    eval "unset ${high_ndx_varname}"
}

#
#  array_get_size - return the size of the array whose name is given by $1.
#                   The size, which is the highest index plus one is written to standard output
#
#    sample call:  size=$(array_get_size my_array)
#

array_get_size ()
{
    local array_name="$1"

    local high_ndx_varname="${array_name}__ARRAY_HIGH_INDEX"
    local high_ndx

    eval "high_ndx=\$${high_ndx_varname}"

    if [ -z "$high_ndx" ]; then
        high_ndx=-1
    fi

    echo $(expr $high_ndx + 1)
}

#
#  array_set_element - set an element to a value.  $1 is the array name, $2 is the element index,
#                      $3 is the element value.
#
#    sample call:  array_set_element my_array index "the new element value"
#

array_set_element ()
{
    local array_name="$1"
    local ndx="$2"
    local elem_value="$3"
    local high_ndx_varname="${array_name}__ARRAY_HIGH_INDEX"
    local elem_varname
    local high_ndx

    # Set specified element to specified value

    elem_varname="${array_name}__${ndx}"

    eval "${elem_varname}=\"${elem_value}\""

    # Adjust high index

    eval "high_ndx=\$${high_ndx_varname}"

    if [ -z "$high_ndx" ]; then
        high_ndx=-1
    fi

    if [ $ndx -gt $high_ndx ]; then
        eval "${high_ndx_varname}=${ndx}"
    fi
}

#
#  array_get_element - get an element's value.  $1 is the array name, $2 is the element index.
#
#    sample call:  value=$(array_get_element my_array index)
#

array_get_element ()
{
    local array_name="$1"
    local ndx="$2"

    eval "echo \"\$${array_name}__${ndx}\""
}

##
##  End of set routines.
##

##
## Begin the means to update apt's view of Ubuntu repo's if necessary.
##

# *** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT ***
# Call apt_get_update_if_repos_changed before ALL apt-* calls. Examples:
#
# apt_get_update_if_repos_changed $REPOFILE
# apt-get install $PACKAGES
#
# apt_get_update_if_repos_changed $REPOFILE
# apt-get -y remove $repo_pkgs_postremove
# *** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT *** IMPORTANT ***

prev_ubuntu_repo_lastmod=

# required argument: REPOFILE
apt_get_update_if_repos_changed()
{
	# Obtain file last modification timestamp. Ignore stderr because file
	# non-existence is not an error, but just another indication of modification.
	# It's okay if REPOFILE isn't set because that is interpreted as acceptable
	# file non-existence.
	curr_ubuntu_repo_lastmod=`stat -c "%y" $1 2>/dev/null`

	if [ "$prev_ubuntu_repo_lastmod" != "$curr_ubuntu_repo_lastmod" ];then
		apt-get -y update 1>/dev/null 2>/dev/null
		prev_ubuntu_repo_lastmod=$curr_ubuntu_repo_lastmod
	fi
}

##
## End the means to update apt's view of Ubuntu repo's if necessary.
##
# Main - start of other pkgs
#do nothing for diskless deployment case because it is done in the image already

RETURNVAL=0

if [ "$(uname -s)" = "AIX" ]; then
      logger -p local4.info -t xcat "otherpkgs not support on AIX, exiting "
      exit 0
  else
      logger -p local4.info -t xcat "Running otherpkgs "
fi
if [ -z "$UPDATENODE" ] || [ $UPDATENODE -ne 1 ]; then
  if [ "$NODESETSTATE" = "netboot" -o \
     "$NODESETSTATE" = "statelite" -o \
     "$NODESETSTATE" = "diskless" -o \
     "$NODESETSTATE" = "dataless" ] 
  then
      echo "  Did not install any extra packages."
      exit 0
  fi
fi 

if [ -z "$OTHERPKGS_INDEX" ]; then 
  echo "$0: no extra rpms to install"
  exit 0
fi

if [ -z "$NFSSERVER" ]; then
    NFSSERVER=$MASTER
fi

if [ -z "$INSTALLDIR" ]; then
    INSTALLDIR="/install"
fi

#check if /install is mounted on the server
mounted=0;
result=`mount |grep " $INSTALLDIR " |grep $NFSSERVER`
if [ $? -eq 0 ]; then
    mounted=1 
fi

if [ -n "$OTHERPKGDIR" ]; then
    OLDIFS=$IFS
    IFS=$','
    dir_array=($OTHERPKGDIR)
    for dir in ${dir_array[@]}
    do
        dirtype=${dir:0:4}
        if [ $dirtype = 'http' ]; then
            OTHERPKGDIR_INTERNET="${OTHERPKGDIR_INTERNET}${dir} ,"
        else
            OTHERPKGDIR_LOCAL=$dir
        fi
    done
    OTHERPKGDIR=$OTHERPKGDIR_LOCAL
    IFS=$OLDIFS
fi

#OTHERPKGDIR is set only when the provmethod is the os image name
#when it is not set, we need to figure it out here
if [ -z "$OTHERPKGDIR" ]; then
    if [ $mounted -eq 0 ]; then
        OTHERPKGDIR="$NFSSERVER$INSTALLDIR/post/otherpkgs/$OSVER/$ARCH"
    else
        OTHERPKGDIR="$INSTALLDIR/post/otherpkgs/$OSVER/$ARCH"
    fi
 
    if ( pmatch "$OSVER" "ubuntu*" ); then
        OTHERPKGDIR=""
    fi 
else
    if [ $mounted -eq 0 ]; then
	OTHERPKGDIR=${NFSSERVER}${OTHERPKGDIR}
    fi
fi

#########################
##start collecting the repositories for os 
if [ -z "$OSPKGDIR" ]; then
    OSPKGDIR="$INSTALLDIR/$OSVER/$ARCH"
fi
    
if [ "$KERNELDIR" != "" ]; then 
    OSPKGDIR="$OSPKGDIR,$KERNELDIR"
fi

    OIFS=$IFS
    IFS=$','
    if ( pmatch "$OSVER" "ubuntu*" ); then
        IFS=$(printf ',')
    fi

    array_ospkgdirs=($OSPKGDIR)   
    IFS=$OIFS
    array_empty os_path
    index=0
    for dir in  ${array_ospkgdirs[@]}  
    do
         
        default_pkgdir="$INSTALLDIR/$OSVER/$ARCH"
        OSPKGDIR="$OSPKGDIR" 
        if [ $mounted -eq 0 ]; then
            #OSPKGDIR="$OSPKGDIR" 
            ospkgdir="$NFSSERVER$dir"
        else 
            ospkgdir="$dir"
        fi
        
        # for the os base pkg dir(default_pkgdir) , there are some special cases.
        # (1)for rhels6, there is one repodata in the os base dir; so keep it here, and handle the other cases below
        # (2)for sles, we should specified the baseurl should be ./install/sles11/ppc64/1
        # (3)for SL5, we should append the /SL
        # (4) for other os, we just keep it here.
        # For other pkg paths, we just keep it here.
        if [ $dir == $default_pkgdir ] || [ $dir == "$default_pkgdir/" ]; then
            if ( pmatch "$OSVER" "sles*" ); then
                OSPKGDIR="$OSPKGDIR/1"
                ospkgdir="$ospkgdir/1"
            elif ( pmatch "$OSVER" "SL5*" ); then
                OSPKGDIR="$OSPKGDIR/SL"
                ospkgdir="$ospkgdir/SL"
            fi
        fi
        array_set_element os_path $index $ospkgdir
         
        if ( pmatch "$OSVER" "rhel*" ); then
            #default_pkgdir="$INSTALLDIR/$OSVER/$ARCH"
            if [ $dir == $default_pkgdir ] || [ $dir == "$default_pkgdir/" ]; then
          
                if ( pmatch "$OSVER" "rhels6*" ); then
                   if [ $ARCH == "ppc64" ]; then
                       ospkgdir_ok="$ospkgdir/Server"
                       index=$(expr $index + 1)          
                       array_set_element os_path $index $ospkgdir_ok
                   fi               
 
                   if [ $ARCH == "x86_64" ]; then
                        for arg in "Server" "ScalableFileSystem" "HighAvailability" "ResilientStorage" "LoadBalancer" 
                        do
                            ospkgdir_ok="$ospkgdir/$arg"
                            index=$(expr $index + 1)          
                            array_set_element os_path $index $ospkgdir_ok
                        done
                    fi               

                elif ( pmatch "$OSVER" "rhels5*" ); then
                     # for rhels5, the repodata is in ./Server, ./Cluster, ./CusterStorage, not in ./
                     ospkgdir_ok="$ospkgdir/Server"
                     array_set_element os_path $index $ospkgdir_ok
               
                     if [ $ARCH == "x86_64" ]; then
                         for arg in "Cluster" "ClusterStorage"
                         do
                             ospkgdir_ok="$ospkgdir/$arg"
                             index=$(expr $index + 1)          
                             array_set_element os_path $index $ospkgdir_ok
                         done
                     fi   # x86_64
                fi # if...elif..fi
             fi  # eq default_pkgdir
          fi    # match rhel*

          index=$(expr $index + 1)          
            
    done    

#fi


if [ "$SDKDIR" != "" ]; then 
    if [ $mounted -eq 0 ]; then
        SDKDIR="$NFSSERVER/$SDKDIR"
    fi
fi

##end collecting the repositories for os 
#########################
if [ $VERBOSE  ]; then
  echo NFSSERVER=$NFSSERVER
fi
logger -p local4.info -t xcat "NFSSERVER=$NFSSERVER"
if [ $VERBOSE  ]; then
  echo OTHERPKGDIR=$OTHERPKGDIR
fi
logger -p local4.info -t xcat "OTHERPKGDIR=$OTHERPKGDIR"

#if [ -x "/sbin/dhcpcd" ]; then
#    dhcpcd -n $PRIMARYNIC
#fi

#check if the node has yum or zypper installed, it will try yum first, then zypper and last rpm 
# for rpm based machines, or check if apt is installed, then it will use apt then dpkg 

hasrpm=0
hasyum=0  
haszypper=0        
hasapt=0
hasdpkg=0
supdatecommand="rpm -Uvh --replacepkgs"
sremovecommand="rpm -ev"

#In ubuntu, rpm can be installed, if rpm is installed,ubuntu will use rpm
#So dpkg --version should be in front of rpm --version
result=`dpkg --version 2>/dev/null`
if [ $? -eq 0 ]; then
    hasdpkg=1
    supdatecommand="dpkg -i"
    sremovecommand="dpkg -r"
    result=`dpkg -l apt`
    if [ $? -eq 0 ]; then
         hasapt=1
    fi
else
    result=`rpm --version 2>/dev/null`
    if [ $? -eq 0 ]; then
         hasrpm=1
         result=`rpm -q yum`
         if [ $? -eq 0 ]; then
              hasyum=1
         else
              result=`rpm -q zypper`
              if [ "$?" = "0" ]; then
              haszypper=1
              fi
         fi
    fi
fi




###########
##start generating the os pkg repositories
if ( pmatch "$OSVER" "sles11*" && [ $haszypper -eq 1 ] ); then
    old_repo=`zypper lr |grep -e "^[0-9]" | cut -f2 -d '|'`
    for x in $old_repo
    do
        if ( ( pmatch "$x" "xCAT-$OSVER*" ) || ( pmatch "$x" "$OSVER-path*" ) || ( pmatch "$x" "xcat-otherpkgs*" ) ); then
             result=`zypper rr "$x"`
        fi
    done
    result=`zypper --non-interactive refresh 2>&1`

    SUM=$(array_get_size os_path)
    i=0
   
    if [ $SUM -eq 0 ]; then 

        if [ $mounted -eq 0 ]; then
	    path="http://$OSPKGDIR"
        else
            path="file://$OSPKGDIR"
        fi
        result=`zypper ar $path xCAT-$OSVER 2>&1`
        if [ $? -ne 0 ]; then 
	    if ( ! pmatch "$result" "*exists*" ); then 
	        logger -t xcat -p local4.info "ospkgs: zypper ar $path xCAT-$OSVER\n    $result"
                if [ $VERBOSE  ]; then
	          echo "ospkgs: zypper ar $path xCAT-$OSVER"
	          echo "    $result"
	        fi
	    fi
        fi
    else 
        while [ $i -lt $SUM ]; do 
            OSPKGDIR=$(array_get_element os_path $i)
            if [ $mounted -eq 0 ]; then
                path="http://$OSPKGDIR"
            else
                path="file://$OSPKGDIR"
            fi
            result=`zypper ar $path xCAT-$OSVER-"path$i"  2>&1`
            if [ $? -ne 0 ]; then 
	        if ( ! pmatch "$result" "*exists*" ); then 
	            logger -t xcat -p local4.info "ospkgs: zypper ar $path xCAT-$OSVER-path$i\n    $result"
                  if [ $VERBOSE  ]; then
	            echo "ospkgs: zypper ar $path xCAT-$OSVER-path$i"
	            echo "    $result"
	          fi
	        fi
            fi
           
            i=$((i+1)) 
        done
    fi

    if [ "$SDKDIR" != "" ]; then
        if [ $mounted -eq 0 ]; then
	    SDKDIR="http://$SDKDIR"
        else
            SDKDIR="file://$SDKDIR"
        fi
        result=`zypper ar $SDKDIR xCAT-$OSVER-sdk 2>&1`
        if [ $? -ne 0 ]; then 
	    if ( ! pmatch "$result" "*exists*" ); then 
		logger -t xcat -p local4.info "ospkgs: zypper ar $SDKDIR xCAT-$OSVER-sdk\n    $result"
                if [ $VERBOSE ]; then
	   	  echo "ospkgs: zypper ar $SDKDIR xCAT-$OSVER-sdk"
		  echo "    $result"
	        fi
	    fi
	fi
    fi
    
    result=`zypper --non-interactive --no-gpg-checks refresh 2>&1` 

elif ( ((pmatch "$OSVER" "rhel*") || (pmatch "$OSVER" "centos*") || (pmatch "$OSVER" "SL*")) && [ $hasyum -eq 1 ] ); then 
    #remove old repo
    mkdir -p /etc/yum.repos.d
    if [ -r "/etc/yum.repos.d/local-repository.repo" ]; then
        result=`rm /etc/yum.repos.d/local-repository.repo 2>&1`
    fi
    rm /etc/yum.repos.d/$OSVER-path*.repo >/dev/null 2>&1
    result=`rm /etc/yum.repos.d/xCAT-$OSVER-path*.repo 2>&1`
    result=`rm /etc/yum.repos.d/xCAT-otherpkgs*.repo 2>&1`

    result=`yum clean all`

    SUM=$(array_get_size os_path)
    i=0
  
      while [ $i -lt $SUM ]; do 
           REPOFILE="/etc/yum.repos.d/xCAT-$OSVER-path$i.repo"
           OSPKGDIR=$(array_get_element os_path $i)


           if [ ! -f $REPOFILE ]; then
	       echo "[xCAT-$OSVER-path$i]" > $REPOFILE
	       echo "name=xCAT-$OSVER-path$i" >> $REPOFILE
	       if [ $mounted -eq 0 ]; then
	           echo "baseurl=http://$OSPKGDIR" >> $REPOFILE
	       else
	           echo "baseurl=file://$OSPKGDIR" >> $REPOFILE
	       fi
	       echo "enabled=1" >> $REPOFILE
	       echo "gpgcheck=0" >> $REPOFILE
           fi
           i=$((i+1)) 
      done  
fi

##end generating the os pkg repositories
###########


###########

# To support the #NEW_INSTALL_LIST# entry in otherpkgs.pkglist files,
# multiple lists of packages are provided to this script in the form:
#  OTHERPKGS1, OTHERPKGS2, ... OTHERPKSn where n=OTHERPKGS_INDEX
# Each sublist will be installed in a separate call (separate pass
#  through this loop)
op_index=1
#echo "OTHERPKGS_INDEX = $OTHERPKGS_INDEX"
while [ $op_index -le $OTHERPKGS_INDEX ]; do 
    eval pkglist=\$OTHERPKGS$op_index
    eval envlist=\$ENVLIST$op_index
    #echo "pkglist = $pkglist"
    if [ $hasyum -eq 1 ]; then 
        mkdir -p /etc/yum.repos.d
        result=`rm /etc/yum.repos.d/xCAT-otherpkgs*.repo 2>&1`
        result=`yum clean all`
        repo_base="/etc/yum.repos.d"
    elif [ $haszypper -eq 1 ]; then
        #remove old repo
        old_repo=`zypper sl |grep xcat-otherpkgs | cut -f2 -d '|'`
        for x in $old_repo
        do
            result=`zypper sd $x`
        done
	result=`zypper --non-interactive refresh 2>&1`
    if [ $VERBOSE  ]; then
	   echo "otherpkgs: zypper --non-interactive refresh"
	   echo "    $result"
	fi
    repo_base="/tmp"
    elif [ $hasapt -eq 1 ] ; then
        mkdir -p /etc/apt/sources.list.d
	result=`rm /etc/apt/sources.list.d/xCAT-otherpkgs*.list 2>&1`
	repo_base="/etc/apt/sources.list.d"
    fi

    array_empty repo_path
    repo_pkgs=""
    repo_pkgs_preremove=""
    repo_pkgs_postremove=""
    plain_pkgs=""
    plain_pkgs_preremove=""
    plain_pkgs_postremove=""
    array_empty handled_path
    for x in `echo "$pkglist" | tr "," "\n"`
    do
        #check if the file name starts with -- or -. 
        #If it is start with -,  then the rpm must be removed before installing other packages
        #If it is start with --, then the rpm will be removed after  installing other packages
        string_type=0;  #nornmal rpm
        pos=`expr index  $x -`
        if [ $pos -eq 1 ]; then 
	    x=`echo ${x#-}`
	    pos=`expr index  $x -`
	    if [ $pos -eq 1 ]; then
	        x=`echo ${x#-}`
	        string_type=1  #start with --
	    else
	        string_type=-1 #start with -
	    fi
        fi
	    
        if [ $hasyum -eq 0 ] && [ $haszypper -eq 0 ] && [ $hasapt -eq 0 ]; then
	    if [  $string_type -eq -1 ]; then
	        plain_pkgs_preremove="$plain_pkgs_preremove $x"
            elif [  $string_type -eq 1 ]; then
	        plain_pkgs_postremove="$plain_pkgs_postremove $x"
	    else
	        plain_pkgs="$plain_pkgs $x*"
	    fi
	    continue
        fi

        if [  $string_type -eq -1 ]; then
	    repo_pkgs_preremove="$repo_pkgs_preremove $x"
        elif [  $string_type -eq 1 ]; then
	    repo_pkgs_postremove="$repo_pkgs_postremove $x"
        else
	    fn=`basename $x`
	    path=`dirname $x`
	    whole_path=$OTHERPKGDIR/$path
	    #whole_path=$OTHERPKGDIR
	
            #find out if this path has already handled
	    try_repo=1
	    rc=1
	    i=0
	    while [ $i -lt $(array_get_size handled_path) ]; do
	        if [ $(array_get_element handled_path $i) = $path ]; then
		    try_repo=0
		    j=0
		    while [ $j -lt $(array_get_size repo_path) ]; do
		        if [ $(array_get_element repo_path $j) = $path ]; then
			    rc=0
			    break
		        fi
		        j=$((j+1))
		    done
		    break 
	        fi
	        i=$((i+1))
	    done
	
	
            #try to add the path to the repo
	    if [ $try_repo -eq 1 ]; then
	        index=$(array_get_size repo_path)
		if [ $hasyum -eq 1 ] || [ $haszypper -eq 1 ] ; then
	            REPOFILE="$repo_base/xCAT-otherpkgs$index.repo"
	            echo "[xcat-otherpkgs$index]" > $REPOFILE
	            echo "name=xcat-otherpkgs$index" >> $REPOFILE
	            if [ $mounted -eq 0 ]; then
		        echo "baseurl=http://$whole_path" >> $REPOFILE
	            else
		        echo "baseurl=file://$whole_path" >> $REPOFILE
	            fi
	            echo "enabled=1" >> $REPOFILE
	            echo "gpgcheck=0" >> $REPOFILE
                if [ $hasyum -eq 1 ]; then
                    yum clean all
                fi
                if [ $haszypper -eq 1 ]; then
	                     result=`zypper --non-interactive refresh 2>&1`
                         if [ $VERBOSE  ]; then
	                       echo "otherpkgs: zypper --non-interactive refresh"
	                       echo "    $result"
	                     fi
                fi
		elif [ $hasapt -eq 1 ] ; then
		    REPOFILE="$repo_base/xCAT-otherpkgs$index.list"
		    if [ -n "$OTHERPKGDIR" ];then
                        if [ $mounted -eq 0 ]; then
		            type=http
	                else
		            type=file
	                fi
                        echo "deb $type://$whole_path ./"  > $REPOFILE
                    fi
                    if [ -n "$OTHERPKGDIR_INTERNET" ];then
                        OLDIFS=$IFS
                        IFS=$','
                        urlarray=($OTHERPKGDIR_INTERNET)
                        for url in ${urlarray[@]}
                        do
                            echo "deb "$url >> $REPOFILE
                        done
                        IFS=$OLDIFS
                    fi
		fi 
	        if [ $hasyum -eq 1 ]; then 
	            #use yum
		    result=`yum list $fn 2>&1`
		    if [ $? -eq 0 ]; then  
		        rc=0
		        array_set_element repo_path $index $path
		    #else
		        #rm $REPOFILE
		    fi
	        elif [ $haszypper -eq 1 ]; then
                    #use zypper
		    if ( pmatch "$OSVER" "sles11*" ); then
		        result=`zypper ar -c $REPOFILE`
		    else
                        result=`zypper sa -r $REPOFILE << EOF
y
EOF`
		    fi	
		
		    result=`zypper --non-interactive refresh xcat-otherpkgs$index 2>&1`
		    if [ $? -eq 0 ]; then  
		        rc=0
		        array_set_element repo_path $index $path
		    else
                        #on sles10, the $? always 1, even the refresh is success.
                        if ( pmatch "$OSVER" "sles10*" ); then
                            rc=0
                            array_set_element repo_path $index $path
                        else
		            result=`zypper sd xcat-otherpkgs$index`
                        fi
		    fi
		elif [ $hasapt -eq 1 ]; then 
		    #use apt
			apt_get_update_if_repos_changed $REPOFILE
			result=`apt-cache show $fn 2>&1`

		    if [ $? -eq 0 ]; then  
		        rc=0
				array_set_element repo_path $index $path
		    else
		        rm $REPOFILE
		    fi

	        fi
	    fi
	
	    if [ $rc -eq 0 ]; then
	        repo_pkgs="$repo_pkgs $fn"  
	    else
                #now no hope we have to use rpm command
	        plain_pkgs="$plain_pkgs $x*"
	    fi
	    array_set_element handled_path $(array_get_size handled_path) $path
        fi
    done  

    #now update all the existing rpms
    if [ $hasyum -eq 1 ]; then 
        if [ $VERBOSE  ]; then
          echo "$envlist yum -y upgrade"
        fi
        result=`eval $envlist yum -y upgrade 2>&1`
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
        fi
        logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
          echo "$result"
        fi
    elif [ $haszypper -eq 1 ]; then
        if [ $VERBOSE  ]; then
          echo "$envlist zypper --non-interactive update --auto-agree-with-license"
        fi
	result=`eval $envlist zypper --non-interactive update --auto-agree-with-license 2>&1`
       
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
        fi
        logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
          echo "$result"
        fi
    elif [ $hasapt -eq 1 ]; then
	apt_get_update_if_repos_changed $REPOFILE
        if [ $VERBOSE  ]; then
	  echo "$envlist  DEBIAN_FRONTEND=noninteractive apt-get -y upgrade"
        fi
	result=`eval $envlist  DEBIAN_FRONTEND=noninteractive apt-get -y upgrade 2>&1`
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
        fi
	logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
	  echo "$result"
        fi
    fi     

    #echo "repo_pkgs=$repo_pkgs,\nrepo_pkgs_preremove=$repo_pkgs_preremove,\nrepo_pkgs_postremove=$repo_pkgs_postremove"
    #echo "plain_pkgs=$plain_pkgs,\nplain_pkgs_preremove=$plain_pkgs_preremove,\nplain_pkgs_postremove=$plain_pkgs_postremove"


    #Now we have parsed the input, let's remove rpms if is specified with -
    if [ "$repo_pkgs_preremove" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            if [ $VERBOSE  ]; then
              echo "$envlist yum -y remove $repo_pkgs_preremove"
            fi 
            result=`eval $envlist yum -y remove $repo_pkgs_preremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
            fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
            fi
        elif [ $haszypper -eq 1 ]; then
            if [ $VERBOSE  ]; then
              echo "$envlist zypper remove -y $repo_pkgs_preremove"
            fi
	    result=`eval $envlist zypper remove -y $repo_pkgs_preremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
            fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
            fi
	elif [ $hasapt -eq 1 ]; then
  	    apt_get_update_if_repos_changed $REPOFILE
            if [ $VERBOSE  ]; then
	      echo "DEBIAN_FRONTEND=noninteractive apt-get -y remove $repo_pkgs_preremove"
            fi
	    result=`DEBIAN_FRONTEND=noninteractive apt-get -y remove $repo_pkgs_preremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
            fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
            fi
        fi
    fi 

    if [ "$plain_pkgs_preremove" != "" ]; then 
        if [ $VERBOSE  ]; then
          echo "$envlist $sremovecommand $plain_pkgs_preremove" 
        fi 
        result=`eval $envlist $sremovecommand $plain_pkgs_preremove 2>&1`
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
        fi
        logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
          echo "$result"
        fi
    fi


    #installation using yum or zypper     
    if [ "$repo_pkgs" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            if [ $VERBOSE  ]; then
             echo "$envlist yum -y install $repo_pkgs"
            fi
            result=`eval $envlist yum -y install $repo_pkgs 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
            fi
	    logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
            fi
        elif [ $haszypper -eq 1 ]; then
            if [ $VERBOSE  ]; then
              echo "$envlist zypper install -y $repo_pkgs"
            fi
	    result=`eval $envlist zypper install -y $repo_pkgs 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	    fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
	    fi
            #remove the repos
            #old_repo=`zypper lr -u |grep xcat-otherpkgs | cut -f2 -d '|'`
            #for x in $old_repo
            #do
            #    result=`zypper sd $x`
            #done
	elif [ $hasapt -eq 1 ]; then
	    apt_get_update_if_repos_changed $REPOFILE
            if [ $VERBOSE  ]; then
	      echo "$envlist DEBIAN_FRONTEND=noninteractive apt-get -q -y --force-yes install $repo_pkgs"
	    fi
	    result=`eval $envlist DEBIAN_FRONTEND=noninteractive apt-get -q -y --force-yes install $repo_pkgs 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	    fi
	    logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
             echo "$result"
	    fi
        fi
    fi 

    #Handle the rest with rpm
    if [ "$plain_pkgs" != "" -a -n "$OTHERPKGDIR" ]; then 
        echo "Warning: the packages $plain_pkgs could not be found in the yum repository, falling back to rpm command. If you want your packages to be installed with yum, verify yum is installed and createrepo has been run."
        logger -p local4.info -t xcat "Warning: the packages $plain_pkgs could not be found in the yum repository, falling back to rpm command. If you want your packages to be installed with yum, verify yum is installed and createrepo has been run." 
        if [ $mounted -eq 0 ]; then
	    dir_no_ftproot=${OTHERPKGDIR#*$INSTALLDIR/}
            mkdir -p /xcatpost/$dir_no_ftproot 
            rm -f -R /xcatpost/$dir_no_ftproot/*
            mkdir -p /tmp/postage/
            rm -f -R /tmp/postage/*
            cd /tmp/postage
    
	    wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -e robots=off -t 0 -T 60 --reject "index.html*" --no-parent http://$OTHERPKGDIR/ 2> /tmp/wget.log  
    
            cd /tmp/postage/$NFSSERVER$INSTALLDIR
            mv $dir_no_ftproot/* /xcatpost/$dir_no_ftproot; 
            rm -rf $dir_no_ftproot
            cd /xcatpost/$dir_no_ftproot
        else
            cd $OTHERPKGDIR
        fi

        if [ $VERBOSE  ]; then
          echo "$envlist $supdatecommand $plain_pkgs" 
        fi
        result=`eval $envlist $supdatecommand $plain_pkgs 2>&1`
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	fi
        logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
          echo "$result"
	fi
    
        if [ $mounted -eq 0 ]; then
	    cd /xcatpost
	    dir_no_ftproot=${OTHERPKGDIR#*$INSTALLDIR/}
            dir_no_ftproot=${dir_no_ftproot%%/*}
            rm -f -R $dir_no_ftproot
        fi
    fi

    #remove more rpms if specified with --
    if [ "$repo_pkgs_postremove" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            if [ $VERBOSE  ]; then
             echo "$envlist yum -y remove $repo_pkgs_postremove"
            fi
            result=`eval $envlist yum -y remove $repo_pkgs_postremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	    fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
	    fi
        elif [ $haszypper -eq 1 ]; then
            if [ $VERBOSE  ]; then
              echo "$envlist zypper remove -y $repo_pkgs_postremove"
	    fi
	    result=`eval $envlist zypper remove -y $repo_pkgs_postremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	    fi
            logger -p local4.info -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
	    fi
        elif [ $hasapt -eq 1 ]; then 
            apt_get_update_if_repos_changed $REPOFILE
            if [ $VERBOSE  ]; then
              echo "$envlist apt-get -y remove $repo_pkgs_postremove"
	    fi
            result=`eval $envlist apt-get -y remove $repo_pkgs_postremove 2>&1`
            R=$?
            if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	    fi
            logger -p local4.info  -t xcat "$result"
            if [ $VERBOSE  ]; then
              echo "$result"
	    fi
        fi
    fi 

    if [ "$plain_pkgs_postremove" != "" ]; then 
        if [ $VERBOSE  ]; then
           echo "$envlist $sremovecommand $plain_pkgs_postremove" 
        fi
        result=`eval $envlist $sremovecommand $plain_pkgs_postremove 2>&1`
        R=$?
        if [ $R -ne 0 ]; then
              RETURNVAL=$R 
	fi
        logger -p local4.info -t xcat "$result"
        if [ $VERBOSE  ]; then
          echo "$result"
	fi
    fi

    op_index=$((op_index+1))
done

exit $RETURNVAL