#!/bin/bash
#---------------------------------------------------------------------
##
## @Synopsis Functions for dispelling a spell
##
##
## @Copyright Original version Copyright 2001 by Kyle Sallee
## @Copyright Additions/Corrections Copyright 2002-4 by the SourceMage Team
##
## Functions for dispelling spells.
#---------------------------------------------------------------------


#---------------------------------------------------------------------
## @Stdin list of files
##
## Given a list of files from standard input, deletes each file.
## Performs a "rm -f" on each file given in standard input, so be
## careful using this function!
##
#---------------------------------------------------------------------
function reap_regular_files()  {
  debug "libsorcery" "reap_regular_files()"
  while  read  FILE;  do  rm  -f   "$FILE";  done;
}


#---------------------------------------------------------------------
## @Stdin list of files
##
## Reads a list of files from standard input.  If the file has been
## modified (md5sum doesn't match the stored md5sum), then function
## C<reap_modified_file> is called.  Otherwise, the file is deleted.
##
#---------------------------------------------------------------------
function reap_config_files()  {

  debug "libsorcery" "reap_config_files()"
  while  read  FILE;  do

    if    grep  -q  "$(  md5sum  "$FILE" )"  "$MD5S"
    then  rm    -f               "$FILE"
    else  reap_modified_file     "$FILE"
    fi

  done

}

#---------------------------------------------------------------------
## @param file
##
## If C<PRESERVE> is off, will move the file to filename.YYYYMMDD.  If
## C<PRESERVE> is on, the file will not be moved.
##
#---------------------------------------------------------------------
function reap_modified_file()  {

  message  "${FILE_COLOR}${1}${DEFAULT_COLOR}"
  message  "${MESSAGE_COLOR}was previously modified by SA?"
  case  $PRESERVE  in
     on)  message  "Therefore, it was not reaped."  ;;
    off)  SAVE="$1.`date  -u  +%Y%m%d`"
          mv  $1  $SAVE
          message  "Therefore, it was moved to"
          message  "${FILE_COLOR}${SAVE}"  ;;
  esac
  message  "${DEFAULT_COLOR}"

}

#---------------------------------------------------------------------
## Removes depends entries for what the spell depends on
#---------------------------------------------------------------------
function reap_depends()  {
  if    [  "$SUSTAIN"  !=  "off"  ]; then
    remove_depends_status  $DEPENDS_STATUS $SPELL
  fi
}


#---------------------------------------------------------------------
## @param file
## @param file
##
## First argument is a file containing a list of files to reap.
## Second argument is a file containing md5 sums of those files, used
## to detect if a config file has been modified.  Config files are any
## files in /etc or any of its sub-directories.
##
#---------------------------------------------------------------------
function reaper()  { (
#  Example:  reaper "$INSTALL_LOG"  "$MD5_LOG"

  debug  "libsorcery" "Running reaper() on $1"

  if  !  [  "$REAP"  ==  "on"  ]   ||
      !  [  -f  $1             ];  then  return
  fi

  MD5S=$2
  MD5S=${MD5S:=/dev/null}

        UNIQUE="$$.$RANDOM"
  REAPER_FILES="/tmp/reaper.$UNIQUE.files"
   REAPER_DIRS="/tmp/reaper.$UNIQUE.dirs"
   REAPER_SYMS="/tmp/reaper.$UNIQUE.syms"

  rm  -f  $REAPER_FILES  $REAPER_DIRS  $REAPER_SYMS

  # convert from TRACK_ROOT to / for protected/excluded filtering,
  # then to INSTALL_ROOT.
  # INSTALL_ROOT is relative to /, TRACK_ROOT is arbitrary.
  sed     "s:^$TRACK_ROOT::" $1   |
  filter  $PROTECTED              |
  filter  $EXCLUDED               |
  sed     "s:^:$INSTALL_ROOT:"    |
  while   read  ITEM;  do
    if    [  -h  "$ITEM"  ];  then  echo  "$ITEM"  >>  $REAPER_SYMS
    elif  [  -f  "$ITEM"  ];  then  echo  "$ITEM"  >>  $REAPER_FILES
    elif  [  -d  "$ITEM"  ];  then  echo  "$ITEM"  >>  $REAPER_DIRS
    fi
  done

  [     -f           $REAPER_FILES  ]  &&
  grep      "^${INSTALL_ROOT}/etc"  $REAPER_FILES     |
  reap_config_files

  [     -f           $REAPER_FILES  ]  &&
  grep  -v  "^/etc"  $REAPER_FILES     |
  reap_regular_files

  [  -f  $REAPER_SYMS   ]  &&  rm     -f  `cat          $REAPER_SYMS`                         2>/dev/null
  [  -f  $REAPER_DIRS   ]  &&  rmdir      `sort  -r     $REAPER_DIRS`                         2>/dev/null
  [  -f  $REAPER_FILES  ]  &&  rmdir      `dirnames  <  $REAPER_FILES  |  uniq  |  sort  -r`  2>/dev/null

  rm  -f  $REAPER_FILES  $REAPER_DIRS  $REAPER_SYMS

) }

#-----
## Checks that a spell is indeed installed. Perhaps this should also see
## if the spell was held?
## @return true Can be dispelled
## @return false Cannot be dispelled
#-----
function dispel_not_possible()  {

  if  !  grep  -q  "^$SPELL:"  $SPELL_STATUS  &&
      !     [  -n  "$EXILE"  ]
  then
    message  "${SPELL_COLOR}${SPELL}"             \
             "${PROBLEM_COLOR}is not installed."  \
             "${DEFAULT_COLOR}"
  else
    false
  fi

}

#-----
## Does the sustained checks for spells
#-----
function dispel_sustained()  {

  if  [  "$SUSTAIN"  ==  "on"  ]  &&
      grep  -q  "^$SPELL$"  $SUSTAINED
  then
    message  "${SPELL_COLOR}${SPELL}"         \
             "${PROBLEM_COLOR}is sustained."  \
             "${DEFAULT_COLOR}"
  else
    false
  fi

}

#-----
## Find out where a spell is located
## @Globals SPELL
#-----
function set_script_directory()  {

           SECTION="`codex_get_spell_section_name  $SPELL`"
  SCRIPT_DIRECTORY="`codex_find_spell_by_name $SPELL`"

}

#-----
## Run the PRE_REMOVE script if it exists
#-----
function pre_remove() {

  if  [  -x  $SCRIPT_DIRECTORY/PRE_REMOVE  ];  then  unset  LD_PRELOAD
           . $SCRIPT_DIRECTORY/PRE_REMOVE
  fi

}

#-----
## Run the POST_REMOVE script if it exists.
#-----
function post_remove() {

  LD_PRELOAD_OLD="$LD_PRELOAD"
  unset LD_PRELOAD

  export  LD_PRELOAD="$LD_PRELOAD_OLD"

  if  [  -x  $SCRIPT_DIRECTORY/POST_REMOVE  ]
  then     . $SCRIPT_DIRECTORY/POST_REMOVE
  fi

}




#---------------------------------------------------------------------
## Dispel a spell
#---------------------------------------------------------------------

function dispel_spell() {
    local SPELL=$1
    if  dispel_sustained  || dispel_not_possible ; then
      DISPEL_EXIT_STATUS=1
      return 1
    fi

    [[ $TRIGGER == off ]] || trigger "pre_dispel"

     VERSION=`installed_version  $SPELL`
    INST_LOG=$INSTALL_LOGS/$SPELL-$VERSION
     MD5_LOG=$MD5SUM_LOGS/$SPELL-$VERSION

    set_script_directory
    pre_remove
    reaper  $INST_LOG  $MD5_LOG &&
    reap_depends                &&
    post_remove                 &&
    remove_spell  $SPELL        &&
    { [[ $TRIGGER == off ]] || trigger "dispel";} &&
    remove_triggers $SPELL      &&
    message  "${DISPEL_COLOR}Dispelled spell:"  \
             "${SPELL_COLOR}${SPELL}"           \
             "${DEFAULT_COLOR}" &&
    activity_log  "dispel"  "$SPELL"  "$VERSION"  "success"
}

#---------------------------------------------------------------------
##
## This software is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This software is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this software; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##
#---------------------------------------------------------------------
