#!/bin/ksh -p
#
# ident "@(#)upgrade_lib.ksh	1.31 08/06/11 SMI"
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

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

function 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 $?
}

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

function 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 $?
}


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

function 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 $?
}

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

function 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 $?
}


#
# function 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
#      

function 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 

function 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:
#    pax 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
#

function SaveDirectory {

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

  pax -w -v -f $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 ! gzip $DIR/$1.tar; then
     rm $DIR/$1.tar* > /dev/null 2>&1
     return 1
  fi

  return $RETURN_VALUE 
}
 

#
# GetCompressedFile <file-prefix>
#
# Description:
#    sets the compressed file name with prefix specified in the _RETURN_VAL.
#    It can either be <file-prefix>.Z for the old compress command or
#    <file-prefix>.gz for the new gzip command.  It prints an error message and
#    sets _RETURN_VAL to blank if both compressed files exist.
#
# Parameters:
#    $1 - the compressed file prefix
#
# Returns:
#    0 success
#    1 otherwise
#
# Globas used:
#    _RETURN_VAL
#
function GetCompressedFile {
  typeset PREF="$1"
  typeset COMPR_FILE=""
  _RETURN_VAL=""

  [[ -z ${PREF} ]] && return 1
  [[ -e ${PREF}.gz ]] && COMPR_FILE=${PREF}.gz
  if [[ -e ${PREF}.Z ]]; then
      if [[ -n "${COMPR_FILE}" ]]; then
          # both compress files exist
	  print -u2 "Error: conflicting compressed files:"\
	  	    "\n\t${COMPR_FILE} and ${PREF}.Z"\
		    "\nPlease check your preserved file."
	  return 1
      fi
      COMPR_FILE=${PREF}.Z
   fi
   [[ -z "$COMPR_FILE" ]] && return 1
   _RETURN_VAL="$COMPR_FILE"
   return 0
}


#
# 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
#

function RestoreDirectory {

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

  GetCompressedFile $ARC
  COMPR_FILE=${_RETURN_VAL}
  [[ -z ${COMPR_FILE} ]] && return 1

  if ! gzip -d ${COMPR_FILE} ; then
     return 1
  fi     
     
  if ! pax -r -f $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
#

function RestoreDirIn {

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

  if [[ ! -f ${COMP_ARC} ]]; then
     if [[ ! -f ${ARC}.Z ]]; then
	# can't find either the old .Z or the new .gz compressed file.
     	return 1
     fi
     COMP_ARC=${ARC}.Z
  fi  
   
  if ! gzip -d ${COMP_ARC} ; then
     return 1
  fi     
     
  if [[ ! -d ${DST} ]]; then
     mkdir -p ${DST}
  fi

  (cd ${DST}; pax -r -s '/^\///' -f ${ARC})
  if [[ $? -ne 0 ]]; 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
#

function 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
#
 
function IsModuleDataPreserved { 

  typeset DIR=$G_UPGRADE_DIR
  typeset VERSION
  typeset COMPR_FILE=""

  GetPreservedVersion
  VERSION=$_RETURN_VAL

  GetCompressedFile ${DIR}/preserve_${VERSION}.tar
  COMPR_FILE="$_RETURN_VAL"

  if [[ -n "${COMPR_FILE}" ]] ; then
     #
     # clean up preserve subdirectory
     #
     rm -rf ${DIR}/preserve > /dev/null 2>&1
 
     #
     # "explode" compressed tar file
     #
     (cd $DIR; gzip -d ${COMPR_FILE})
     if [[ $? -ne 0 ]]; then
        return 1
     fi
  fi

  if [[ ! -d ${DIR}/preserve ]] && [[ -e ${DIR}/preserve_${VERSION}.tar ]]
  then
     (cd $DIR; pax -r -f ${DIR}/preserve_${VERSION}.tar)
     if [[ $? -ne 0 ]]; 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  
#

function 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  
#

function 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.{gz,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
#

function 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
#
function GetCurrentSRVersion {

  _RETURN_VAL=""

  if $G_MEDIA_DIR/utprodinfo -t installed SUNWutr; then
     _RETURN_VAL=$($G_MEDIA_DIR/utprodinfo -p SUNWutr PRODVERS)
     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
#
function 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
#
function OldPreservedExist {
    if [[ -f ${G_OLD_PRESERVED_FILE} ]]; then
	_RETURN_VAL=$(cat ${G_OLD_PRESERVED_FILE})
	return 0
    fi
    _RETURN_VAL=""
    return 1
}
