#! /bin/sh
# bourne shell script
#
# This is the original RTM version that this patch applies to
VERSION="6.0,REV=2003.10.29"

#
# debug message
#
debug_log() {
  if [ $DEBUG != 0 ]; then
    log_msg $*
  fi
}

#
# initialize LOGFILE
#
log_init() {
  /usr/bin/touch $LOGFILE
  /usr/bin/echo "============ LOGFILE started `date` ==========" >> $LOGFILE
}

#
# log a message to the screen and to the LOGFILE
#
log_msg() {
  /usr/bin/echo $*
  /usr/bin/echo $* >> $LOGFILE
}

#
# log a message to the LOGFILE only
#
log_only() {
  /usr/bin/echo $* >> $LOGFILE
}

#
# determine basedir
# - sets the variable basedir
#
get_basedir() {   # start of get_basedir
  PKGS=`/bin/ls -d $PKGDB/SUNWmsgco*`
  # did we find the right PKG
  found=0
  for dir in $PKGS
  do
    pkgname=`basename $dir`
    basedir=`pkgparam -R $ROOTDIR $pkgname BASEDIR`
    version=`pkgparam -R $ROOTDIR $pkgname VERSION`
    if [ $version = "$VERSION" ]; then
      found=1
      break
    fi
  done
  if [ $ROOTDIR != "/" ]; then
    basedir=${ROOTDIR}$basedir
  fi
  # what if we do not find the pkg? should not possible...
  if [ $found -eq 0 ]; then
    /usr/bin/echo "Error in postpatch, did not find a SUNWmsgco that matches expected VERSION: $VERSION"
    exit 1
  fi
}

#
# create the patch staging area
# - sets the variables: PATCHDIR BACKOUTDIR SAVEDIR
#
create_staging_area() {
  log_only "-- creating patch directory $PATCHDIR"
  /usr/bin/mkdir -p $PATCHDIR/backout $PATCHDIR/save
  BACKOUTDIR=$PATCHDIR/backout
  SAVEDIR=$PATCHDIR/save
}

#
# these set of files are always filtered regardless of whether there is
# a configuration. This is from postinstall.install
#
filter_special_files() {
  log_only "-- filter special files"
# only sbin/configure needs to be patched right now
#  FILTERFILES="lib/config-templates/DevsetupDefaults.properties lib/config-templates/installer.properties sbin/configure sbin/useconfig"
  FILTERFILES="$basedir/sbin/configure"
  for f in $FILTERFILES
  do
  # use cp to preserve permissions
    /usr/bin/cp -p $f $f.orig
    /usr/bin/sed -e "s:<msg.RootPath>:$basedir:" -e "s/<INSTALLER_TYPE>/PKGADD/" $f.orig > $f
    /usr/bin/rm $f.orig
  done
}

#
# was configure run previously? AND there is configure_YYYYMM... directory
# - the second case corresponds to when a useconfig was used.
#
# - sets the variable isConfigured to either 0 or 1
# - requires basedir
# - set CONFIGDIRS if system is configured, this is a list of the
#   configure_YYYYMM... directories in time stamp order (latest first)
#
get_isConfigured() {
  if [ -r $basedir/config/imta_tailor ]; then
    # have to use the latest install/configure_YYYYMM... directory
    CONFIGDIRS=`/bin/ls -dt $basedir/install/configure_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] 2> $LOGFILE`
    if [ -z "$CONFIGDIRS" ]; then
      # list is empty
      isConfigured=0
    else
      # list is not null
      isConfigured=1
    fi
  else
    isConfigured=0
  fi
  log_only "-- isConfigured = $isConfigured"
}

#
# read saveState file for configuration variables
# - given basedir
# - get iMS.UserId, iMS.GroupId, INSTALLER_TYPE, SCHEMA_TYPE, comp list
# - set the variables
#   saveState         shell variable
#   ---------         --------------
#   iMS.UserId     -> user
#   iMS.GroupId    -> group
#   INSTALLER_TYPE -> INSTALLER_TYPE
#   SCHEMA_TYPE    -> SCHEMA_TYPE
#   com.iplanet.install.panels.common.ComponentPanel.selectedcomponents
#                  -> compList
read_saveState() {
  # determine saveState file
  for dir in $CONFIGDIRS
  do
    saveState=$dir/saveState
    if [ -f $saveState ]; then
      break
    fi
  done
  log_only "-- saveState file: $saveState"
  set `/usr/bin/grep iMS.UserId $saveState`
  user=$3
  log_only "-- user: $user"
  set `/usr/bin/grep iMS.GroupId $saveState`
  group=$3
  log_only "-- group: $group"
  set `/usr/bin/grep SCHEMA_TYPE $saveState`
  SCHEMA_TYPE=$4
  log_only "-- SCHEMA_TYPE: $SCHEMA_TYPE"
  set `/usr/bin/grep com.iplanet.install.panels.common.ComponentPanel.selectedcomponents $saveState`
  compList=$3
  log_only "-- compList: $compList"
  # should be PKGADD, what should I do if it is not?
  set `/usr/bin/grep INSTALLER_TYPE $saveState`
  INSTALLER_TYPE=$4
  log_only "-- INSTALLER_TYPE: $INSTALLER_TYPE"
}

#
# create config.ins and devtypes.txt
# substitute for msg.RootPath, local.serveruid, local.servergid, INSTALLER_TYPE
# - variables used $basedir, $user, $group, $INSTALLER_TYPE
#
create_configins() {
  log_only "-- creating config.ins and devtypes.txt"
  log_only "/usr/bin/mkdir -p $BACKOUTDIR/lib/config-templates"
  /usr/bin/mkdir -p $BACKOUTDIR/lib/config-templates
  # devtypes.txt.template
  if [ ! -f $BACKOUTDIR/lib/config-templates/devtypes.txt ]; then
    log_only "/usr/bin/cp -p $basedir/lib/config-templates/devtypes.txt $BACKOUTDIR/lib/config-templates/devtypes.txt"
    /usr/bin/cp -p $basedir/lib/config-templates/devtypes.txt $BACKOUTDIR/lib/config-templates/devtypes.txt
  fi
  log_only "/usr/bin/sed -e \"s/<local.serveruid>/$user/\" -e \"s/<local.servergid>/$group/\" -e \"s:<msg\.RootPath>:$basedir:\" -e \"s/<\INSTALLER_TYPE>/${INSTALLER_TYPE}/\" $basedir/lib/config-templates/devtypes.txt.template > $basedir/lib/config-templates/devtypes.txt"
  /usr/bin/sed -e "s/<local.serveruid>/$user/" \
      -e "s/<local.servergid>/$group/" \
      -e "s:<msg\.RootPath>:$basedir:" \
      -e "s/<\INSTALLER_TYPE>/${INSTALLER_TYPE}/" \
    $basedir/lib/config-templates/devtypes.txt.template \
  > $basedir/lib/config-templates/devtypes.txt 2>> $LOGFILE

  # config.ins.template
  if [ ! -f $BACKOUTDIR/lib/config-templates/config.ins ]; then
    log_only "/usr/bin/cp -p $basedir/lib/config-templates/config.ins $BACKOUTDIR/lib/config-templates/config.ins"
    /usr/bin/cp -p $basedir/lib/config-templates/config.ins $BACKOUTDIR/lib/config-templates/config.ins
  fi
  log_only "/usr/bin/sed -e \"s/<local.serveruid>/${user}/\" -e \"s/<local.servergid>/${group}/\" -e \"s:<msg\.RootPath>:$basedir:\" -e \"s/<\INSTALLER_TYPE>/${INSTALLER_TYPE}/\" $basedir/lib/config-templates/config.ins.template > $basedir/lib/config-templates/config.ins"
  /usr/bin/sed -e "s/<local.serveruid>/${user}/" \
      -e "s/<local.servergid>/${group}/" \
      -e "s:<msg\.RootPath>:$basedir:" \
      -e "s/<\INSTALLER_TYPE>/${INSTALLER_TYPE}/" \
    $basedir/lib/config-templates/config.ins.template \
    > $basedir/lib/config-templates/config.ins 2>> $LOGFILE
}

#
# run_devinstall
# - uses several variable for input
#
run_devinstall() {
  log_only "----- Running devinstall"
  # determine pkglist, add schematype and compList
  #  should also check for INSTALLER_TYPE, but it is supposed to be PKGADD
  pkglist="pkgcfg:config:msg:msg_en"
  case $SCHEMA_TYPE in
    1 )   pkglist="schema1:$pkglist";;
    1.5 ) pkglist="schema2compat:schema1:$pkglist";;
    2 )   pkglist="schema2native:$pkglist";;
  esac
  # compList is comma separated need to make it colon separated
  compList=`/usr/bin/echo $compList|/usr/bin/sed -e s/,/:/g`
  pkglist="$pkglist:$compList"
  log_only "-- pkglist = $pkglist"
  # see if I need to copy Devsetup.properties
  if [ ! -f $basedir/lib/config-templates/Devsetup.properties ]; then
    # extract configure_ directory from saveState
    configDir=`/usr/bin/dirname $saveState`
    log_only "/usr/bin/cp -p $configDir/Devsetup.properties $basedir/lib/config-templates"
    /usr/bin/cp -p $configDir/Devsetup.properties $basedir/lib/config-templates
  fi
  #
  log_only "$basedir/lib/devinstall -n -m -P -v -l $pkglist -i $basedir/lib/config-templates/config.ins -P $basedir/lib $basedir/lib/config-templates > $PATCHDIR/install.list"
  $basedir/lib/devinstall \
    -n -m -P -v -l $pkglist -i $basedir/lib/config-templates/config.ins \
    $basedir/lib $basedir/lib/config-templates \
    > $PATCHDIR/install.list 2>> $LOGFILE
  /usr/bin/egrep '^=F' $PATCHDIR/install.list | /usr/bin/nawk '{print $5}' | \
    /usr/bin/sed -e "s:^$basedir/::" > $PATCHDIR/file.list 2>> $LOGFILE
  for f in `/usr/bin/cat $PATCHDIR/file.list`
  do
    dir=`/usr/bin/dirname $BACKOUTDIR/$f`
    if [ ! -d $dir ]; then
      log_only "/usr/bin/mkdir -p $dir"
      /usr/bin/mkdir -p $dir >> $LOGFILE 2>&1
    fi
    if [ ! -f $BACKOUTDIR/$f ]; then
      log_only "/usr/bin/cp -p $basedir/$f $BACKOUTDIR/$f"
      /usr/bin/cp -p $basedir/$f $BACKOUTDIR/$f >> $LOGFILE 2>&1
    fi
  done
  # Now do it for real
  log_only "$basedir/lib/devinstall -m -P -v -l $pkglist -i $basedir/lib/config-templates/config.ins -P $basedir/lib $basedir/lib/config-templates > $PATCHDIR/install.list"
  $basedir/lib/devinstall \
    -m -P -v -l $pkglist -i $basedir/lib/config-templates/config.ins \
    $basedir/lib $basedir/lib/config-templates >> $LOGFILE 2>&1
}

#
# patch config files
# - attempt to patch the user files, but do not actually overwrite
# - These are config files that do not have substitutions in them.
#   so they are "easier" for me to patch
patch_config() {
  log_only "-- patch_config being run"
  set `/usr/bin/cat $PATCHDIR/config.list`
  while [ $# -ne 0 ]
  do
    # the "template" file
    tfile=$1
    shift
    # the "config" file
    cfile=$1
    shift
    # backup the $cfile
    dir=`dirname $SAVEDIR/$cfile`
    if [ ! -d $dir ]; then
      log_only "/usr/bin/mkdir -p $dir"
      /usr/bin/mkdir -p $dir >> $LOGFILE 2>&1
    fi
    if [ ! -f $SAVEDIR/$cfile ]; then
      log_only "/usr/bin/cp -p $basedir/$cfile $SAVEDIR/$cfile"
      /usr/bin/cp -p $basedir/$cfile $SAVEDIR/$cfile >> $LOGFILE 2>&1
    fi
    # diff3
    log_only "/usr/bin/cp -p $basedir/$cfile $SAVEDIR/$cfile.new"
    /usr/bin/cp -p $basedir/$cfile $SAVEDIR/$cfile.new >> $LOGFILE 2>&1
    # diff3 will core dump if the file does not end in a newline
    # so add a new line if it is missing
    log_only "lines=\`/usr/bin/tail -1 $SAVEDIR/$cfile.new | /usr/bin/wc -l\`"
    lines=`/usr/bin/tail -1 $SAVEDIR/$cfile.new | /usr/bin/wc -l`
    log_only "lines=$lines"
    if [ $lines -eq 0 ]; then
     log_only "-- Adding extra line to $SAVEDIR/$cfile.new"
      /usr/bin/echo "" >> $SAVEDIR/$cfile.new
    fi
    #
    log_only "/usr/bin/diff3 -E $SAVEDIR/$cfile.new $BACKOUTDIR/$tfile $basedir/$tfile > $SAVEDIR/$cfile.script"
    /usr/bin/diff3 -E $SAVEDIR/$cfile.new $BACKOUTDIR/$tfile $basedir/$tfile > $SAVEDIR/$cfile.script 2>> $LOGFILE
    stat=$?
    log_only "stat=$stat"
    if [ $stat -ne 0 ]; then
      log_msg "--"
      log_msg "-- diff3 failed with status=$stat for"
      log_msg "--   $basedir/$cfile"
      log_msg "-- Please merge changes by hand from the new file"
      log_msg "--   $basedir/$tfile"
    else
      log_only "(/usr/bin/cat $SAVEDIR/$cfile.script; /usr/bin/echo '1,\$p') | /usr/bin/ed - $SAVEDIR/$cfile.new"
      (/usr/bin/cat $SAVEDIR/$cfile.script; /usr/bin/echo '1,$p') | /usr/bin/ed - $SAVEDIR/$cfile.new >> $LOGFILE 2>&1
      log_only "/usr/bin/cmp $basedir/$cfile $SAVEDIR/$cfile.new"
      /usr/bin/cmp $basedir/$cfile $SAVEDIR/$cfile.new >> $LOGFILE 2>&1
      stat=$?
      if [ $stat -ne 0 ]; then
	log_msg "-- "
	log_msg "-- A New version of"
        log_msg "--   $basedir/$cfile"
        log_msg "-- is available under"
	log_msg "--   $SAVEDIR/$cfile.new"
        log_only "/usr/bin/grep -s '^=======$' $SAVEDIR/$cfile.script"
	/usr/bin/grep -s '^=======$' $SAVEDIR/$cfile.script
	stat=$?
	if [ $stat -eq 0 ]; then
	  log_msg "-- However there were diff3 conflicts in the file"
	  log_msg "-- You need to resolve the conflicts and install the new"
	  log_msg "-- file by hand"
	else
	  log_msg "-- Please copy it to"
	  log_msg "--   $basedir/$cfile"
          log_msg "-- to install the new version"
	fi
      else
	log_only "-- No patch required for $basedir/$cfile"
      fi
    fi
  done
}

#
#
# perform_custom
#
perform_custom() {
  log_only "-- perform_custom being run"
}

#
# main program starts here
#
# Do I need to do stop-msg?
# determine server-root
# create patch staging area (for backout and new files to apply)
# determine ifConfigured
# if configured
#   - read saveState
#     - get schema type, comp list, iMS.UserId, iMS.GroupId
#   - generate config.ins and devtypes.txt
#   - run devinstall
#   - install new files, backup old ones.
#   - do custom stuff
# endif

get_basedir
PATCHDIR=$basedir/install/patch/$PatchNum
/usr/bin/mkdir -p $PATCHDIR
LOGFILE=$PATCHDIR/postpatch_`date +%Y%m%d%H%M%S`.log
log_init
create_staging_area
filter_special_files
get_isConfigured
if [ $isConfigured -eq 1 ]; then
  read_saveState
  create_configins
  run_devinstall
  patch_config
  perform_custom
fi
