#!/bin/ksh
#
# ident "@(#)upgrade_lib.ksh	1.23 02/09/18 SMI"
#
# Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
#


#
# upgrade_lib.ksh
#
# Functions  used by upgrade
#

#
# DoUpgrade()
#
# Description:
#         Upgrades fields by keyvalue
#    
# Parameters:
#      $1 - key, $2 - old value, $3 - new value, $4 - newfile 
#
#

DoUpgrade() {
  typeset -r key="$1"
  typeset -r old_keyval="$(echo $2 | sed 's;/;\\/;g')"
  typeset -r new_keyval="$(echo $3 | sed 's;/;\\/;g')"
  typeset -r newfile="$4"

  chmod u+w $newfile 2>&-
  # the "-" after ed tells ed that this is not interactive
  ed - $newfile <<-! 2>/dev/null 1>&2
	g/^[ 	]*${key}[= 	]*/s/^${new_keyval}/${old_keyval}/
	w
	q
	!
  return $?
}

#
# UpdateFields()
#
# Description:
#      Updates fields in a file
#
# Parameters: 
#     $1 - oldfile, $2 - newfile 
#
#

UpdateFields() {
  typeset -r oldfile=$1
  typeset -r newfile=$2
  typeset key=""

  if [[ ! -r $newfile ]]; then
    echo "Cannot read $newfile"
    return 1
  fi
  for key in $(awk -F= '{ print $1 }' $oldfile 2>&- | grep -v "^#" |
      sort -u); do
    old_keyval=$(grep "^[ 	]*$key[= 	]" $oldfile 2>&- |
        tail -1)
    new_keyval=$(grep "^[ 	]*$key[= 	]" $newfile 2>&- |
        tail -1)
    if [[ -n "$old_keyval" && -n "$new_keyval" ]]; then
      if [[ "$old_keyval" != "$new_keyval" ]]; then
        DoUpgrade "$key" "$old_keyval" "$new_keyval" "$newfile"
      fi
    fi
  done
  return $?
}


#
# DoAppend() 
#
# Description:
#       Appends line to file
#     
#
# Parameters:
#     $1 - line to append to file, $2 - file to be appended 
#

DoAppend() {
  typeset -r line="$1"
  typeset -r file="$2"

  if [[ -w "$file" ]]; then
    echo "$line" >> "$file"
  else
    chmod u+w "$file" 2>&-
    echo "$line" >> "$file"
    chmod u-w "$file" 2>&-
  fi
  return $?
}

#
# AppendFields()
#
# Description:
#     Appends fields to a file  
#
# Parameters:
#    $1 - oldfile, $2 - newfile 
#

AppendFields() {
  typeset -r oldfile=$1
  typeset -r newfile=$2
  typeset key=""
  typeset line=""

  if [[ ! -r $newfile ]]; then
    echo "Cannot read $newfile"
    return 1
  fi
  for key in $(grep -v "^#" "$oldfile" 2>&- | awk -F= '{ print $1 }' |
      sort -u); do
    line=$(grep "^${key}[ 	=]" "$oldfile" 2>&- | tail -1)
    grep "$line" "$newfile" 2>&1 >/dev/null || \
      DoAppend "$line" "$newfile"
  done
  return $?
}


#
# SaveFiles()
#
# Description:
#    To save the files into a subdirectory 
#                /var/tmp/SUNWut.upgrade/preserve/<module name>
#
# Parameters:
#             $1 $2 ...$n   - full pathnames of files to be saved.
#
# Globals used :
#
#      _MODULE_NAME
#      

SaveFiles() {

  typeset DIR=${G_UPGRADE_DIR}/preserve/${_MODULE_NAME}

  if [ ! -d $DIR ]; then
     mkdir -p $DIR
     chmod 775 $DIR
  fi


  while [[ $# != 0 ]]
  do
     dstdir=$(dirname ${DIR}${1})
     if [[ ! -e $dstdir ]]; then
        mkdir -p $dstdir >/dev/null 2>&1
     fi

     if [[ -e $1 ]]; then
        if ! cp -p $1 ${DIR}${1} ; then
           return 1
	else
          echo "$1"
        fi
     fi
     shift

  done

  return 0 
}

#
# GetPreservedFilePath
#
# 
# Description:
#    Returns full pathname from the temporary directory.
#
# Parameters :
#    $1  - is full pathname of file
#
# Globals used :
#
#    G_UPGRADE_DIR
#    _MODULE_NAME
#    _RETURN_VAL 

GetPreservedFilePath() {

  typeset DIR=${G_UPGRADE_DIR}/preserve/${_MODULE_NAME}

  if [[ -f ${DIR}${1} ]]; then
 
     _RETURN_VAL=${DIR}${1}
     return 0
  else
     return 1
  fi  

}
 
#
# SaveDirectory <arc_file> <list of dir>
#
#
# Description:
#    tar and compress a list of directories and their contents into archive
#    /var/tmp/SUNWut.upgrade/preserve/<module name>/<arc_file>
#    return 0 if succeeded, 1 otherwise (failure)
#
# Parameters :
#    $1 - name of the archive.
#    $2 - list of directories (full path and space separated). 
#
# Global used :
#    _MODULE_NAME
#    G_UPGRADE_DIR
#

SaveDirectory() {

  typeset DIR=$G_UPGRADE_DIR/preserve/$_MODULE_NAME
  typeset TEMP=$@
  typeset RETURN_VALUE="0"

  tar -cvf $DIR/$1.tar ${TEMP#* } 2>/dev/null | cut -f2 -d' '
  RETURN_VALUE=$? 
  if [[ $RETURN_VALUE != "0" && $RETURN_VALUE != "1" ]]; then
     rm $DIR/$1.tar > /dev/null 2>&1
     return 1
  else
     #
     # it TAR returns 1 means that some directory does not exist. it is not 
     # considered a failure, anyway.

     RETURN_VALUE="0"
  fi

  if ! compress -f $DIR/$1.tar; then
     rm $DIR/$1.tar* > /dev/null 2>&1
     return 1
  fi

  return $RETURN_VALUE 
}
 

#
# RestoreDirectory <name>
#
#
# Description:
#    restores directory from archive created by function SaveDirectory() 
#    /var/tmp/SUNWut.upgrade/preserve/<module name>/<arc_file>
#
# Parameters :
#    $1 - archive  name as originally passed to SaveDirectory()
#
# Globals used :
#    G_UPGRADE_DIR
#    _MODULE_NAME
#

RestoreDirectory() {

  typeset RETURN_VALUE
  typeset ARC=${G_UPGRADE_DIR}/preserve/${_MODULE_NAME}/$1.tar

  if [[ ! -f ${ARC}.Z ]]; then
     return 1
  fi  
   
  if ! uncompress ${ARC}.Z ; then
     return 1
  fi     
     
  if ! tar -xf $ARC; then  
     return 2
  fi
   
  rm $ARC > /dev/null 2>&1 
  return 0
}

#
# RestoreDirIn <newroot> <name>
#
#
# Description:
#    restores directory from archive created by function SaveDirectory() 
#    /var/tmp/SUNWut.upgrade/preserve/<module name>/<arc_file>
#    It restores the data into the chroot directory  <newroot>.
#
# Parameters :
#    $1 - chroot directory
#    $2 - archive  name as originally passed to SaveDirectory()
#
# Globals used :
#    G_UPGRADE_DIR
#    _MODULE_NAME
#

RestoreDirIn() {

  typeset RETURN_VALUE
  typeset ARC=${G_UPGRADE_DIR}/preserve/${_MODULE_NAME}/$2.tar
  typeset DST=$1

  if [[ ! -f ${ARC}.Z ]]; then
     return 1
  fi  
   
  if ! uncompress ${ARC}.Z ; then
     return 1
  fi     
     
  if [[ ! -d ${DST} ]]; then
     mkdir -p ${DST}
  fi

  cp ${ARC} ${DST}
  if [[ ! -x ${DST}/tar ]]; then
     cp /usr/sbin/static/tar ${DST}
  fi

  if ! chroot ${DST} tar -xf $2.tar; then  
     return 2
  fi
   
  rm $ARC > /dev/null 2>&1
  return 0
}


#
# IsDataPreserveD
#
# Description :
#    Checks the existence of /var/tmp/SUNWut.upgrade/preserve_<version>.tar.z
#    returns 0 if it exists (1 if it is absent) to calling environment.     
#
# Parameters :
#    (None)
#
# Globals used :
#    G_UPGRADE_DIR
#    _RETURN_VAL
#

IsDataPreserved() {

  GetPreservedTarVersion
  return $?

}

#
# IsModuleDataPreserved
#
# Description :
#    Checks that " /var/tmp/SUNWut.upgrade/preserve_<version>.tar.z "   
#    contains    " /var/tmp/SUNWUT/$_MODULE_NAME" returns 0 if it does, 
#    1 otherwise.
#
# Parameters :
#    (None)
#
# Globals used :
#    G_UPGRADE_DIR
#    _MODULE_NAME
#    _RETURN_VAL
#
 
IsModuleDataPreserved() { 

  typeset DIR=$G_UPGRADE_DIR
  typeset VERSION

  GetPreservedVersion
  VERSION=$_RETURN_VAL

  if [[ -e ${DIR}/preserve_${VERSION}.tar.Z ]] ; then
     #
     # clean up preserve subdirectory
     #
     rm -r ${DIR}/preserve > /dev/null 2>&1
 
     #
     # "explode" compressed tar file
     #
     cd $DIR 
     if ! uncompress ${DIR}/preserve_${VERSION}.tar.Z ; then
        return 1
     fi
  fi

  if [[ ! -d ${DIR}/preserve ]] && [[ -e ${DIR}/preserve_${VERSION}.tar ]]
  then
     cd $DIR 
     if ! tar -xf ${DIR}/preserve_${VERSION}.tar ; then
        return 2
     fi
  fi  
     
  if [[ -d ${DIR}/preserve/${_MODULE_NAME} ]]; then 
     return 0
  fi

  return 1  
}

#
# GetPreservedVersion
#
# Description :
#    Returns the version number for the SunRay software for which data has 
#    been preserved.  It also returns in the _RETURN_FILENAMES variable
#    the names of the preserved files/directories found under the preserved
#    directory SUNWut.upgrade.
#	
# Parameters :
#    (None)
#
# Globals used :
#    G_UPGRADE_DIR
#    _RETURN_VAL  
#

GetPreservedVersion() {

  typeset VERSIONFILE=${G_UPGRADE_DIR}/version.txt       
  typeset VERSION=""
  typeset TARFILE=""
 
  #
  # check for the version file along with the preserve directory under
  # /var/tmp/SUNWut.upgrade directory.  Don't use the version file without
  # the preserve directory where the preserved file resides.
  #
  if [[ -e $VERSIONFILE && -d ${G_UPGRADE_DIR}/preserve ]] ; then
  
     _RETURN_VAL=$(cat $VERSIONFILE)
     _RETURN_FILENAMES="${G_UPGRADE_DIR}/preserve ${VERSIONFILE}"

     return 0

  else

     GetPreservedTarVersion
     return $?
  fi

  return 1

}

#
# GetPreservedTarVersion
#
# Description :
#    Returns the version number from ONLY the tarfile for the SunRay software
#    for which data has been preserved.  It also returns in the _RETURN_FILENAMES
#    variable the name of the preserved tarfile found under the preserved
#    directory SUNWut.upgrade.
#	
# Parameters :
#    (None)
#
# Globals used :
#    _RETURN_VAL  
#

GetPreservedTarVersion() {
    _RETURN_VAL=""
    _RETURN_FILENAMES=""
    if GetLatestFile; then
        typeset TARFILE=$_RETURN_VAL

        if [[ -e $TARFILE ]] ; then

	   _RETURN_FILENAMES=${TARFILE}
	   # extract the version number from either *.tar.Z and *.tar filename
           TARFILE=${TARFILE##*_} 
           VERSION=${TARFILE%%.tar*}
           _RETURN_VAL=$VERSION
 
	   return 0
        fi
    fi     
    return 1
}



#
# GetLatestFile
#
# Description :
#    Returns the full path to latest preserve archive
#
# Parameters :
#    (None)
#
# Globals used :
#    _RETURN_VAL
#

GetLatestFile() {

  typeset TARFILE=$G_UPGRADE_DIR/preserve_

  if ! ls ${TARFILE}* 1> /dev/null 2>&- ; then
    _RETURN_VAL=""
    return 1
  fi

  _RETURN_VAL=$(ls -1 ${TARFILE}* | tail -1)

  return 0

}


#
# GetCurrentSRVersion
#
# Description :
#    Returns the version of the Sun Ray software currently installed.
#    return 0 if succeeded. _RETURN_VAL will contain the Sun Ray version.
#    return 1 otherwise (no Sun Ray installed).
#
# Parameters :
#    (None)
#
# Globals used :
#    _RETURN_VAL
#
GetCurrentSRVersion() {

  _RETURN_VAL=""
  if pkginfo -q SUNWutr; then
     _RETURN_VAL=$(pkgparam SUNWutr VERSION | cut -d_ -f1)
     return 0
  fi
  return 1
}

#
# SaveCurrentSRVersion
#
# Description :
#    Save the version of the installed Sun Ray software into a text
#    file (version.txt). This file lives in the preserve/upgrade temporary
#    directory and it is used to know where the preserved data are coming
#    from (during the upgrade process).
#
# Parameters :
#    (None)
#
# Globals used :
#    _RETURN_VAL
#    G_UPGRADE_DIR
#
SaveCurrentSRVersion() {

  if GetCurrentSRVersion; then
     mkdir -p ${G_UPGRADE_DIR} > /dev/null 2>&1
     echo $_RETURN_VAL > ${G_UPGRADE_DIR}/version.txt
  fi
  return 0
}


#
# OldPreservedExist
#
# Description:
#    Check to see if there is an old preserved file in the $G_UPGRADE_DIR
#    directory.  This is done by touching a file named USE_OLD_PRESERVED
#    (defined in $G_OLD_PRESERVED_FILE).
#    If this file exist, no preserve should be done during the upgrade
#    and restore should be performed regardless if the software was
#    originally installed or not.
#
# Globals used :
#    _RETURN_VAL
#    G_UPGRADE_DIR
#    G_OLD_PRESERVED_FILE
#
OldPreservedExist() {
    if [[ -f ${G_UPGRADE_DIR}/${G_OLD_PRESERVED_FILE} ]]; then
	_RETURN_VAL=$(cat ${G_UPGRADE_DIR}/${G_OLD_PRESERVED_FILE})
	return 0
    fi
    _RETURN_VAL=""
    return 1
}
