############################################################
#                                                          #
# subroutines - Lunar subroutines                          #
#                                                          #
############################################################
#                                                          #
# this WAS the subroutines of a source based Linux distro, #
# calls Sorcerer GNU/Linux, or SGL. SGL is no longer       #
# available with GPL license. Since this script was taken  #
# before licensing scheme change, no legal problems I      #
# guess.                                                   #
#                                                          #
# the code is re-written for Lunar. The previous Copyright #
# notices are kept; just in case some code is left :=)     #
# Kagan Kongar <kongar@tsrsb.org.tr>, 20020519             #
#                                                          #
############################################################
#                                                          #
# Copyright 2001 by Kyle Sallee                            #
#                                                          #
# Parts Copyrighted Hendrik Visage 2002 under GPLv2        #
#                                                          #
# Parts Copyrighted Kagan Kongar 2002 under GPLv2          #
#                                                          #
############################################################

# the below is for running the code located in subroutines
# under $FUNCTIONS subdirectory.
if [ -d "$FUNCTIONS" ]
then
   for FILE in `echo $FUNCTIONS/*.lunar`
   do
      [ -s "$FILE" ] && . "$FILE"
   done
fi

#lets get the BUILD if it is not defined   
  [ -z "$BUILD" ] && optimize_cpu $CPU
  [ -n "$BUILD" ] && export BUILD || 
  echo "Set your optimization preferences via lunar"
#


# function : directories
# usage    : VARIABLE=`directories < dirlistfile`
# purpose  : to determine the directories from a given list
directories() {
  while  read       ITEM;  do
    if  [     -d  "$ITEM"  ]   &&
        [  !  -h  "$ITEM"  ];  then
      echo        "$ITEM"
    fi
  done
}


# function : files
# usage    : VARIABLE=`files < dirlistfile`
# purpose  : to determine the ordinary files from a given list
files()  {
  while  read       ITEM;   do
    if  [     -f  "$ITEM"  ]   &&
        [  !  -h  "$ITEM"  ];  then
      echo        "$ITEM"
    fi
  done
}


# function : sysmlinks
# usage    : VARIABLE=`symlinks < dirlistfile`
# purpose  : to determine the symbolic links from a given list
symlinks()  {
  while  read    ITEM;   do
    if  [  -h  "$ITEM"  ];  then
      echo     "$ITEM"
    fi
  done
}


# function : dirnames
# usage    : VARIABLE=`dirnames < dirlistfile`
# purpose  : info about the real locations of symlinks
dirnames() {  while  read  FILE;  do  dirname  "$FILE";  done;  }


# function : exists
# usage    : VARIABLE=`exists < dirlistfile`
# purpose  : filter out the non-existent files in a list
exists()  {  while  read  ITEM;  do  [  -e  $ITEM  ]  &&  echo  $ITEM;  done;  }


# function : guess_filename
# usage    : guess_filename <filename>
# purpose  : fuzzy check for the existance of the filename
guess_filename()  {
  FILENAME=$1
  BASENAME=`echo  $FILENAME         |
            sed  "s/\.tar\.gz$//"   |
            sed  "s/\.tgz$//"       |
            sed  "s/\.tar\.bz2$//"`

  if    [  -f  $FILENAME          ];  then  echo  $FILENAME
  elif  [  "$FUZZY"  ==  "off"    ];  then  return  1
  elif  [  -f  $BASENAME.tar.gz   ];  then  echo  $BASENAME.tar.gz
  elif  [  -f  $BASENAME.tar.bz2  ];  then  echo  $BASENAME.tar.bz2
  elif  [  -f  $BASENAME.tgz      ];  then  echo  $BASENAME.tgz
  else  false
  fi
}


unpack() {

    FILENAME=`guess_filename  $SOURCE_CACHE/$1`          &&
  COMPRESSOR=`file  -b  $FILENAME  |  cut  -d ' '  -f1`  &&

  verbose_msg "Unpacking $FILENAME in $(pwd)"

  case  $COMPRESSOR  in
        bzip2)  bzip2  -cdf  $FILENAME  |  tar  -xf  -  ;;
         gzip)  gzip   -cdf  $FILENAME  |  tar  -xf  -  ;;
    compress*)  gzip   -cdf  $FILENAME  |  tar  -xf  -  ;;
          Zip)  unzip  -q    $FILENAME                  ;;
          RPM)  rpmunpack  < $FILENAME  |  gzip  -d     \
                                        |  cpio  -idm   ;;
            *)  false                                   ;;
  esac
  [ -n "$SOURCE_DIRECTORY" ] &&
  [ -d "$SOURCE_DIRECTORY" ]
  
  if [[ `echo $CFLAGS | grep fbranch-probabilities` ]]; then
    chown -R 777 $SOURCE_DIRECTORY 2>&1 >/dev/null
  else
    chown -R root:root $SOURCE_DIRECTORY 2>&1 >/dev/null 
  fi
}


boost_locked()  {

  [  -f     $BOOST_LOCK  ]  &&
  ps  `cat  $BOOST_LOCK`    |
  grep  -q  lin

}


save_libraries()  {

  [ "$MODULE" == "glibc" ] && return 0

  verbose_msg "saving libraries if any"

  OLD_VERSION=`installed_version  $MODULE`
  OLD_LOG=$INSTALL_LOGS/$MODULE-$OLD_VERSION

  [ -e "$OLD_LOG" ] || return 0      

  OLD_LIBS=$SOURCE_DIRECTORY/old.libraries
  mkdir  -p  $OLD_LIBS

  SAVED=$OLD_LIBS/$MODULE.saved.libraries
  rm  -rf  $SAVED

  grep   "/lib/"  $OLD_LOG  |
  while  read  LINE;  do

    if   [  -f      $LINE   ]  &&
         file  -bL  $LINE   |
         grep  -q   "shared object"
    then
      verbose_msg "saving $LINE"
      if  [  -h  $LINE  ];  then
        DEST=$(  basename  $(  ls   -la  "$LINE"  |
                               cut  -d  '>'  -f2  |
                               cut  -c  2-
                            )
              )
        ln  -sf  $DEST  $OLD_LIBS/`basename  $LINE`
      else
        cp  $LINE  $OLD_LIBS
      fi
      echo  $OLD_LIBS/`basename  $LINE`  >>  $SAVED
    fi
  done

  ldconfig  $OLD_LIBS

  if  [  -z   "$LD_LIBRARY_PATH"  ]
  then  export  LD_LIBRARY_PATH="$OLD_LIBS"
  else  export  LD_LIBRARY_PATH="$OLD_LIBS:$LD_LIBRARY_PATH"
  fi
}


release_saved_libraries()  {

   verbose_msg "releasing saved libraries if any"
   
   OLD_LIBS=$SOURCE_DIRECTORY/old.libraries
   SAVED=$OLD_LIBS/$MODULE.saved.libraries

   [  -f  $SAVED  ]    &&
   cat    $SAVED       |
   while  read  FILE;  do
     verbose_msg "rm -f \"$FILE\""
     rm  -f   "$FILE"
   done

   ldconfig  $OLD_LIBS

}


prepare_install() {
  if  module_installed $MODULE  || module_held $MODULE ; then
    message  "${MESSAGE_COLOR}Preparing to install"  \
             "${MODULE_COLOR}${MODULE}${DEFAULT_COLOR}"

    while  boost_locked;  do
      sleep  5
    done

    echo  $$  >  $BOOST_LOCK

    save_libraries
    verbose_msg "calling \"lrm --keepconfig --nosustain $MODULE\""
    lrm  --keepconfig  --nosustain  $MODULE
    true
  fi
}


rm_source_dir() {

  [ "$KEEP_SOURCE" == "on" ] && return 0

  cd  $BUILD_DIRECTORY

  DEAD_DIR=$1
  DEAD_DIR=${DEAD_DIR:=$SOURCE_DIRECTORY}

  verbose_msg "destroying building dir \"$DEAD_DIR\""

  if [ "$TMPFS" != "off" ]; then
    umount     $DEAD_DIR  2>  /dev/null
    rmdir      $DEAD_DIR  2>  /dev/null
  else
    rm   -rf   $DEAD_DIR  2>  /dev/null
  fi

  rm     -f  $BOOST_LOCK

}


mk_source_dir() {

  cd  $BUILD_DIRECTORY

  NEW_DIR=$1
  NEW_DIR=${NEW_DIR:=$SOURCE_DIRECTORY}

  verbose_msg "creating building dir \"$NEW_DIR\""

  if [ "$TMPFS" != "off" ]; then 
    umount  $NEW_DIR  2>/dev/null
    rmdir   $NEW_DIR  2>/dev/null
    mkdir  -p  $NEW_DIR  &&
    mount  -o  size=1g,nr_inodes=1m  -t  tmpfs  tmpfs  $NEW_DIR
  else
    rm -rf  $NEW_DIR  2>/dev/null
    mkdir  -p  $NEW_DIR
  fi

}


validate_source_dir()  {

  verbose_msg "validating \"$SOURCE_DIRECTORY\""
  if  [  -n    "$SOURCE_DIRECTORY"                                   ]  &&
      [        "$SOURCE_DIRECTORY"  !=           "$BUILD_DIRECTORY"  ]  &&
      echo     "$SOURCE_DIRECTORY"  |  grep  -q  "$BUILD_DIRECTORY"
  then
    true
  else
    message  "\$SOURCE_DIRECTORY and \$BUILD_DIRECTORY must not be the same."
    message  "\$SOURCE_DIRECTORY must not be empty."
    message  "\$SOURCE_DIRECTORY must be a subdirectory of \$BUILD_DIRECTORY"
    false
  fi

}


# Usage: bad_flags "list of flags to remove"
# Example: bad_flags -ffast-math -funroll-loops
bad_flags() {

  verbose_msg "bad_flags \"$@\""
  if [[ $1 == "ALL" ]]; then
    unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS
  elif [[ $1 == "compiler" ]]; then
    unset CFLAGS CXXFLAGS CPPFLAGS
  elif [[ $1 == "linker" ]]; then
    unset LDFLAGS
  else
    for BAD_FLAG in $@; do
      CFLAGS=`echo $CFLAGS | sed s/$BAD_FLAG//`
      CXXFLAGS=`echo $CXXFLAGS | sed s/$BAD_FLAG//`
      CPPFLAGS=`echo $CPPFLAGS | sed s/$BAD_FLAG//`
      LDFLAGS=`echo $LDFLAGS | sed s/$BAD_FLAG//`
    done
  fi
}


default_pre_build() {
  verbose_msg "running default_pre_build"
  if [[ $CVS_SERVER ]]; then
    validate_source_dir  $SOURCE_DIRECTORY
    if [[ -d $SOURCE_DIRECTORY ]] &&
       [[ $KEEP_SOURCE == "on" ]]; then
      cd $SOURCE_DIRECTORY &&
      make clean
    else
      mk_source_dir        &&
      cd                   $SOURCE_DIRECTORY &&
      unpack               $MODULE-$VERSION.tar.bz2
    fi
  else
    validate_source_dir  $SOURCE_DIRECTORY 
    if [[ -d $SOURCE_DIRECTORY ]] &&
       [[ $KEEP_SOURCE == "on" ]]; then
      cd $SOURCE_DIRECTORY && 
      make clean
    else
      mk_source_dir        $SOURCE_DIRECTORY &&
      unpack               $SOURCE
    fi
  fi
}


default_config() 
{
   verbose_msg "running default_config"

   verbose_msg "CFLAGS=$CFLAGS"                &&
   verbose_msg "OPTS=$OPTS"                    &&
   verbose_msg "./configure --build=$BUILD --prefix=/usr --sysconfdir=/etc --localstatedir=/var --infodir=/usr/share/info --mandir=/usr/share/man $OPTS"

   ./configure  --build=$BUILD            \
                --prefix=/usr             \
                --sysconfdir=/etc         \
                --localstatedir=/var      \
                --infodir=/usr/share/info \
                --mandir=/usr/share/man   \
                $OPTS
} > $C_FIFO 2>&1


default_cvs_config() {
   verbose_msg "running default_cvs_config"

   verbose_msg "CFLAGS=$CFLAGS"                &&
   verbose_msg "OPTS=$OPTS"                    &&
   verbose_msg "./autogen.sh --build=$BUILD --prefix=/usr --sysconfdir=/etc --localstatedir=/var --infodir=/usr/share/info --mandir=/usr/share/man $OPTS"

   ./autogen.sh --build=$BUILD            \
                --prefix=/usr             \
                --sysconfdir=/etc         \
                --localstatedir=/var      \
                --infodir=/usr/share/info \
                --mandir=/usr/share/man   \
                $OPTS
} > $C_FIFO 2>&1


default_make() {
   verbose_msg "running default_make"
   make                               &&
   prepare_install                    &&
   make    install
} > $C_FIFO 2>&1


default_build() {
   verbose_msg "running default_build"
   default_config  &&
   default_make
} > $C_FIFO 2>&1


default_cvs_build() {
   verbose_msg "running default_cvs_build"
   default_cvs_config  &&
   default_make
} > $C_FIFO 2>&1


default_post_build() {
  {
    gather_docs

    install_pam_confs
    install_services
    install_xinetd_confs
    install_initd
    install_bashmisc
  } | tee -a $C_LOG

  devoke_installwatch
  ldconfig
  release_saved_libraries
  cd  /
}


# function : remove_module
# usage    : remove_module; but $MODULE must be defined earlier
# purpose  : removed a module from the MODULE_STATUS files, no source removal
remove_module() {

  verbose_msg "updating lunar state files after module removal"
  lock_file $MODULE_STATUS                                     && 
  lock_file $MODULE_STATUS_BACKUP                              &&
  grep  -v  "^$1:" $MODULE_STATUS_BACKUP  >  $MODULE_STATUS 2>/dev/null
  cat $MODULE_STATUS >  $MODULE_STATUS_BACKUP               2>/dev/null
  unlock_file $MODULE_STATUS_BACKUP                            &&
  unlock_file $MODULE_STATUS 

  if  [  -n  "$EXILE"  ];  
  then
     lock_file $MODULE_STATUS                            && 
     lock_file $MODULE_STATUS_BACKUP                     &&
     echo  "$1::exiled:0.0"  >>  $MODULE_STATUS          &&
     cat  $MODULE_STATUS      >  $MODULE_STATUS_BACKUP   &&
     unlock_file $MODULE_STATUS_BACKUP                   &&
     unlock_file $MODULE_STATUS 

     lock_file $DEPENDS_STATUS                           &&
     lock_file $DEPENDS_STATUS_BACKUP                    &&
     grep  -v  ":$1:" $DEPENDS_STATUS_BACKUP  >   $DEPENDS_STATUS  &&
     cat $DEPENDS_STATUS >  $DEPENDS_STATUS_BACKUP       &&
     unlock_file $DEPENDS_STATUS                         &&
     unlock_file $DEPENDS_STATUS_BACKUP
  fi
}

# function: add_module
# usage   : add_module <module_name>
# purpose : adds the 1st parameter as the module name to the MODULE_STATUS files
add_module()  {
  verbose_msg "updating lunar state files after module installation"
  lock_file $MODULE_STATUS                                    && 
  lock_file $MODULE_STATUS_BACKUP                             &&
  grep  -v  "^$1:" $MODULE_STATUS_BACKUP   >   $MODULE_STATUS 2>/dev/null  &&
  echo  "$1:`date  -u  +%Y%m%d`:$2:$3:$4"  >>  $MODULE_STATUS &&
  cat  $MODULE_STATUS      >  $MODULE_STATUS_BACKUP           &&
  unlock_file $MODULE_STATUS_BACKUP                           &&
  unlock_file $MODULE_STATUS 
}


conflicts() {
  if  module_installed  $1;  then
    lrm $1
  fi

  true

} 


filter() {

  if  [  -f  $1  ];  then

     DIRS=`directories  <  $1  2>/dev/null`
    FILES=`files        <  $1  2>/dev/null`
     SYMS=`symlinks     <  $1  2>/dev/null`

    RID_LIST=`for  DIR   in  $DIRS;   do  echo  -n  "^$DIR\|";     done
              for  FILE  in  $FILES;  do  echo  -n  "^$FILE\$\|";  done
              for  SYM   in  $SYMS;   do  echo  -n  "^$SYM\$\|";   done
              echo  -n  "/dev/null"`

    grep  -v  "$RID_LIST"

  else
    cat
  fi

}


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}"

}


reap_regular_files()  {  while  read  FILE;  do  rm  -f   "$FILE";  done;  }


reap_config_files()  {

  while  read  FILE;  do

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

  done

}


reaper()  { (
#  Example:  reaper "$INSTALL_LOG"  "$MD5_LOG"

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

  export  IFS="$TAB_ENTER_IFS"

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

           UNIQUE="`uuidgen`"
     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

  filter  $PROTECTED  <  $1  |
  filter  $EXCLUDED          |
  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      "^/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

) }

push_install_queue() {
 
  remove_queue   $REMOVE_QUEUE    "$1"
  remove_queue   $INSTALL_QUEUE   "$1"
  !  module_installed             "$1"  &&
  add_queue  $INSTALL_QUEUE       "$1"
    
}


push_remove_queue() {

  remove_queue   $INSTALL_QUEUE  "$1"
  remove_queue   $REMOVE_QUEUE   "$1"
  module_installed               "$1"  &&
  add_queue  $REMOVE_QUEUE       "$1"
    
}


# function : sort_install_queue
# usage    : sort_install_queue
# purpose  : sorts the install queue according to the dependencies
sort_install_queue() {

   if ! [ -s $INSTALL_QUEUE ]; then return; fi

   message  "${MESSAGE_COLOR}Sorting module dependencies...${DEFAULT_COLOR}"

   export   TMP_DEPENDS="/tmp/lunar_tmp_depends.$$"
   rm -f $TMP_DEPENDS 2>/dev/null

   export   TMP_INSTALL="/tmp/lunar_install_queue.$$"
   rm -f $TMP_INSTALL 2>/dev/null

   cp $INSTALL_QUEUE $TMP_INSTALL || return 1

   for MODULE in `cat $TMP_INSTALL`; do
     show_fancy_progress "Processing: $MODULE"
     find_depends $MODULE
   done

   for LINE in `tsort $TMP_DEPENDS 2>/dev/null`; do
      if grep -q "^$LINE\$" $TMP_INSTALL 2>/dev/null; then
         remove_queue $INSTALL_QUEUE $LINE
         add_queue    $INSTALL_QUEUE $LINE
      fi
   done
   rm -f $TMP_DEPENDS 2>/dev/null
   rm -f $TMP_INSTALL 2>/dev/null
}

# function : show_fancy_progress
# usage    : show_fancy_progress <fancy_progress_var_string>
# purpose  : display progress ex: show_fancy_progress "Processing: $MODULE"
function show_fancy_progress
{
   echo -en "\r                                                                            \r$1\r"
}

# function : update_installed
# usage    : update_installed
# purpose  : add the packages which will be updated  into the INSTALL_QUEUE
update_installed()  {

  message  "${MESSAGE_COLOR}Searching installed modules for upgrade..." \
           "${DEFAULT_COLOR}"
  rm  -f  $INSTALL_QUEUE
  for  LINE  in  $(cat $MODULE_STATUS | sort);  do

      MODULE=`echo  "$LINE"  |  cut  -d : -f1`
       IDATE=`echo  "$LINE"  |  cut  -d : -f2`
      STATUS=`echo  "$LINE"  |  cut  -d : -f3`
    IVERSION=`echo  "$LINE"  |  cut  -d : -f4`

    show_fancy_progress "Processing: $MODULE"

    if  [  "$STATUS"  ==  "installed"  ];  then

      if ! run_details $MODULE &> /dev/null  ; then
      
        message "${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} was removed from ${FILE_COLOR}${MOONBASE}${DEFAULT_COLOR}"
      
        if query "Do you want to remove ${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${QUERY_COLOR} ?" y ; then
	  lrm $MODULE
          continue
	else
	  message "${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} is kept and can be removed manually later${DEFAULT_COLOR}"
	  echo
	fi
	
      else

        if  [  "$VERSION"   !=  "$IVERSION"   ]  ||
            [  -z  "$IDATE"                   ]  ||
            ((  "$UPDATED"  >   "$IDATE"  ))
        then
          if    [  "$MODULE"  !=  "lunar"  ] && [  "$MODULE"  !=  "theedge"  ]
          then  add_queue  $INSTALL_QUEUE $MODULE
          fi
        fi
     
     fi

    fi
  done
  sort_install_queue
}

# function : upgrade_install_queue
# usage    : upgrade_install_queue
# purpose  : optionally edit INSTALL_QUEUE, install modules, fix and prune
upgrade_install_queue()  {

  if  [  -f  $INSTALL_QUEUE  ];  then

    message  "The following modules will be updated:"
    cat  $INSTALL_QUEUE
    unset  MODULE
    if    query  "Do you wish to edit ${FILE_COLOR}$INSTALL_QUEUE${QUERY_COLOR} ?" n
    then  edit_file  $INSTALL_QUEUE
    fi

    if  [  -n  "`cat  $INSTALL_QUEUE`"  ];  then
      export  LOGTMP=$$_`date +%s`
      lin      `cat  $INSTALL_QUEUE`         
      rm             $INSTALL_QUEUE
    fi

  fi

  if  [  "$AUTOFIX"  ==  "on"  ];  then
    message  "${MESSAGE_COLOR}Executing AUTOFIX :    lin --fix${DEFAULT_COLOR}"
    lin --fix
  fi

  if  [  "$AUTOPRUNE"  ==  "on"  ];  then
    message  "${MESSAGE_COLOR}Executing AUTOPRUNE :  lunar prune${DEFAULT_COLOR}"
    prune
  fi

  display_update_log update

}


log_list()  {

   echo `cat  $MODULE_STATUS_BACKUP                | \
         cut  -d  :  -f1,4 --output-delimiter="-"`

}


clean_logs()  {

  LOGS=`log_list`

  for  FILE  in  `ls  $INSTALL_LOGS`;  do
    if  !  echo  -e  "$LOGS"  |  grep  -q  $FILE;  then
      message  "Removing stale log  :  $INSTALL_LOGS/$FILE"
      rm                               $INSTALL_LOGS/$FILE
    fi
  done

  for  FILE  in  `ls  $COMPILE_LOGS | sed  "s/\.bz2//"`;  do
    if  !  echo  -e  "$LOGS"  |  grep  -q  $FILE;  then
      message  "Removing stale log  :  $COMPILE_LOGS/$FILE.bz2"
      rm                               $COMPILE_LOGS/$FILE.bz2
    fi
  done

  for  FILE  in  `ls  $MD5SUM_LOGS`;  do
    if  !  echo  -e  "$LOGS"  |  grep  -q  $FILE;  then
      message  "Removing stale log  :  $MD5SUM_LOGS/$FILE"
      rm                               $MD5SUM_LOGS/$FILE
    fi
  done

}

activity_log()  { (

    DATE=`date  -u  +%Y%m%d-%T`
  COMMAND=$1
   MODULE=$2
  VERSION=$3
  OUTCOME=$4
     INFO=$5

  lock_file $ACTIVITY_LOG &&
  echo "$DATE	$COMMAND	$MODULE	$VERSION	$OUTCOME	$INFO"  >> $ACTIVITY_LOG &&
  unlock_file $ACTIVITY_LOG
) }


invoke_installwatch()  {
  if  [  -e  /usr/lib/installwatch.so  ];  then
    export  INSTALLWATCHFILE=/tmp/$MODULE.iw
    export  LD_PRELOAD=/usr/lib/installwatch.so
  fi
}


devoke_installwatch()  {
  unset  LD_PRELOAD
}


syms_not_owned()  {

  cat  $1  |
  while  read  ITEM;  do

    if  [  -h  "$ITEM"  ]   &&
        [  -f  "$ITEM"  ];  then

      DEST=$(  basename  $(  ls   -la  "$ITEM"  |
                             cut  -d  '>'  -f2  |
                             cut  -c  2-
                          )
            )

      if  !  grep  -q  "$DEST"  "$1"
      then   echo  -n  "$ITEM\|"
             echo      "$ITEM"  >>  /tmp/$MODULE.rejected.symlinks
      fi

    fi

  done

}


parse_iw()  {

  OMIT="^/dev\|^/tmp\|^/usr/src"
  OMIT_IN="	rename\|	symlink\|	unlink"

  grep -v "$OMIT_IN" $IW_LOG | cut -f3 | grep -v "$OMIT"
  cat                $IW_LOG | cut -f4 | grep -v "$OMIT" | grep "^/"

}




track()  {

  message  "${MESSAGE_COLOR}Creating ${FILE_COLOR}${INST_LOG}${DEFAULT_COLOR}"

  export  IFS="$TAB_ENTER_IFS"

  parse_iw                   |
  sort                       |
  uniq                       |
  filter  "$EXCLUDED"        |
  filter  "$LOCAL_EXCLUDED"  |
  exists                     >  $TMP_LOG

  echo  "$C_LOG_BZ"         >>  $TMP_LOG
  echo  "$MD5_LOG"          >>  $TMP_LOG
  echo  "$INST_LOG"         >>  $TMP_LOG

  MISOWNED_SYMLINKS=`syms_not_owned  $TMP_LOG
                     echo  -n  "/dev/null"`

  if    [  "$MISOWNED_SYMLINKS"  ==  "/dev/null"  ]
  then  cp  $TMP_LOG  $INST_LOG
  else  grep  -v  "$MISOWNED_SYMLINKS"  $TMP_LOG  >  $INST_LOG
  fi

  verbose_msg "removing \"$IW_LOG\""
  rm  -f  $IW_LOG  $TMP_LOG
}


archive()  {

  LINES=`wc  -l  <  $INST_LOG`
  ((  CHUNKS     =  LINES  /  1024  ))
  ((  REMAINDER  =  LINES  %  1024  ))
  if  ((  REMAINDER  !=  0  ));  then
    ((  CHUNKS++  ))
  fi

  ((  START  =  1     ))
  ((  STOP   =  1024  ))

  for  ((  CX  =  0  ;  CX  !=  CHUNKS  ;  CX++  ));  do

    md5sum  $(  sed  -n  ${START},${STOP}p  $INST_LOG  |
                files  )  >> $MD5_LOG

    ((  START   =  STOP  +  1  ))
    ((  STOP   +=  1024        ))

  done

  if    [  "$ARCHIVE"  ==  "off"  ]
  then  return
  fi

  ((  START  =  1     ))
  ((  STOP   =  1024  ))

  for  ((  CX  =  0  ;  CX  !=  CHUNKS  ;  CX++  ));  do
 
    tar  --no-recursion  \
         -rPf  $CACHE    \
         $(  sed  -n ${START},${STOP}p  ${INST_LOG}  )

    ((  START   =  STOP  +  1  ))
    ((  STOP   +=  1024        ))

  done

  message  "${MESSAGE_COLOR}Creating ${FILE_COLOR}${CACHE_BZ}${DEFAULT_COLOR}"
  bzip2  -9f  <  $CACHE  >  $CACHE_BZ
  rm     -f      $CACHE  

}


boost()	{ (

     CACHE="/tmp/$MODULE-$VERSION-$BUILD.tar"
  CACHE_BZ="$INSTALL_CACHE/$MODULE-$VERSION-$BUILD.tar.bz2"
  C_LOG_BZ="$COMPILE_LOGS/$MODULE-$VERSION.bz2"
   TMP_LOG="/tmp/$MODULE-$VERSION"
  INST_LOG="$INSTALL_LOGS/$MODULE-$VERSION"
   MD5_LOG="$MD5SUM_LOGS/$MODULE-$VERSION"
    IW_LOG="/tmp/$MODULE.iw"

  rm  -f   $CACHE
  rm  -f   $INST_LOG
  touch    $INST_LOG
  rm  -f   $TMP_LOG
  rm  -f   $MD5_LOG
  touch    $MD5_LOG

  track    &&
  archive  &&
  add_module  $MODULE installed $VERSION `find_module_size $MODULE $VERSION`

  rm  -f  $BOOST_LOCK

) }


find_pam_aware()  { (

  cat  $MODULE_STATUS_BACKUP  |
  while  read  LINE;  do
                        
    MODULE="`echo  $LINE  |  cut  -d  :  -f1`"
    STATUS="`echo  $LINE  |  cut  -d  :  -f3`"
                                              
    if  [  "$STATUS"  ==  "installed"  ]   ||
        [  "$STATUS"  ==  "held"       ];  then

      SECTION=`find_section  $MODULE`
                                    
      if    [  -d  "$MOONBASE/$SECTION/$MODULE/pam.d"  ]  &&
            [  "$MODULE"  !=  "Linux-PAM"              ]
      then  echo  $MODULE
      fi

    fi
  done

) }


verify_source()  
{

  VERIFIED="true"

  for  SOURCE_FILE  in  $@;  do
    if  !  guess_filename  $SOURCE_CACHE/$1  >/dev/null
    then
      message  "${PROBLEM_COLOR}Missing ${FILE_COLOR}${1}${DEFAULT_COLOR}"
      message  "${PROBLEM_COLOR}Lunar Install aborting.${DEFAULT_COLOR}"
      activity_log  "lin"  "$MODULE"  "$VERSION"  "failed"  \
                    "because it was missing source:  $1"
      VERIFIED=false
      break
    fi
  done

  $VERIFIED
}


# function : generate_keep_list
# usage    : generate_keep_list
# purpose  : generated a list of files which will not be deleted with prune
generate_keep_list()  
{
  for  SECTION  in  `list_sections`;  do
    for  MODULE  in  `list_modules $SECTION`;  do
      show_fancy_progress "Processing: $SECTION/$MODULE" 
      sources  $MODULE >> $KEEP
      echo     $MODULE-$VERSION-$BUILD.tar.bz2 >> $KEEP
    done
  done
  echo  README >> $KEEP
}

prune()  
{
  message  "${MESSAGE_COLOR}Generating a keep list..." \
           "${DEFAULT_COLOR}"

  KEEP="/tmp/prune.keep.$$"
  trap "rm -f $KEEP 2>/dev/null; exit" INT QUIT TERM
  generate_keep_list

  message  "${MESSAGE_COLOR}Now pruning $SOURCE_CACHE..." \
           "${DEFAULT_COLOR}"
  ls  $SOURCE_CACHE  |
  while  read  FILE;  do
      grep  -q  "^$FILE$"  $KEEP  || {
        rm  $SOURCE_CACHE/$FILE 2>/dev/null
	verbose_msg "rm \"$SOURCE_CACHE/$FILE\""
      }
  done

  message  "${MESSAGE_COLOR}Now pruning $INSTALL_CACHE..." \
           "${DEFAULT_COLOR}"
  ls  $INSTALL_CACHE  |
  while  read  FILE;  do
      grep  -q  "^$FILE$"  $KEEP  || {
        rm  $INSTALL_CACHE/$FILE 2>/dev/null
	verbose_msg "rm \"$SOURCE_CACHE/$FILE\""
      }	
  done

  KEEP2="/tmp/prune.instlist.$$"
  trap "rm -f $KEEP2 2>/dev/null; exit" INT QUIT TERM
  cat $MODULE_STATUS | cut -d: -f1,4 | sed 's/:/-/' > $KEEP2

  message  "${MESSAGE_COLOR}Now pruning $INSTALL_LOGS..." \
             "${DEFAULT_COLOR}"
  ls  $INSTALL_LOGS  |
  while  read  FILE;  do
      grep -q "^$FILE$"   $KEEP2 || {
        rm $INSTALL_LOGS/$FILE
	verbose_msg "rm \"$SOURCE_CACHE/$FILE\""
      }
  done

  message  "${MESSAGE_COLOR}Now pruning $COMPILE_LOGS..." \
             "${DEFAULT_COLOR}"
  ls  $COMPILE_LOGS  | sed 's/.bz2$//' |
  while  read  FILE;  do
      grep -q "^$FILE$"    $KEEP2 || {
        rm $COMPILE_LOGS/$FILE.bz2
	verbose_msg "rm \"$SOURCE_CACHE/$FILE\""
      }
  done

  message  "${MESSAGE_COLOR}Now pruning $MD5SUM_LOGS..." \
             "${DEFAULT_COLOR}"
  ls  $MD5SUM_LOGS  |
  while  read  FILE;  do
      grep -q "^$FILE$"    $KEEP2 || {
        rm $MD5SUM_LOGS/$FILE
	verbose_msg "rm \"$SOURCE_CACHE/$FILE\""
      }
  done

  rm  -f  $KEEP 2>/dev/null
  rm  -f  $KEEP2 2>/dev/null
  trap INT QUIT TERM
}


verify_sources()  {  md5_verify_source  `sources  $MODULE MD5`;  }

op_conflicts(){
   RETVALUE=true
   ([ "$OPTIMIZATIONS" == "none" ] && $RETVALUE) && return
   if `echo $OPTIMIZATIONS | grep speedy | grep -q tiny`  ; then
      $DIALOG  --msgbox  \
      "speedy (-03) and tiny (-Os) are not compatible!" 8 40
      RETVALUE=true
   else
      RETVALUE=false
   fi 
   $RETVALUE
}


# function : enviro_check
# usage    : enviro_check
# purpose  : check if the environment is sane
enviro_check()
{
#check is SHELL is defined
   set | grep -q "^SHELL=" || {
      echo  ""
      echo "The SHELL environment variable is NOT defined"
      echo "If you are using su, consider using su -"
      echo  ""
      return 1
   }
   return 0
}

# function : root_check
# usage    : root_check
# purpose  : check if the user is root
root_check()
{
   [ "$UID" == "0" ] && return 0

   echo  ""
   echo "User must have root privileges to run this program"
   echo  ""
   return 1
}


# check the environment to continue!!
enviro_check || return 1
