############################################################
#                                                          #
# 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 : edit_file
# usage    : edit_file FILENAME
# purpose  : to edit a file
edit_file()  {  ${EDITOR:-nano}  $1;  }


# 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 : sedit
# usage    : sedit "sed string" filename
# purpose  : sed edit a file;  example  : sedit "s/TEST/TSET/" filename
sedit()  {
  message "${MESSAGE_COLOR}Editing ${FILE_COLOR}${2}${DEFAULT_COLOR}"
  sed -i~ "$1" "$2" 
}


# 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 : return_error
# usage    : return_error error_string $FUNCTION
# purpose  : return info if a function is called with wrong params, exits imm.
return_error() {
   echo "$1 in function $2"
   exit
}

sound()  {

  case  $SOUND  in
    on)  SOUND_FILE=$SOUND_DIRECTORY/$SOUND_THEME/$1
         if  [  -e  $SOUND_FILE  ];  then
           (  cd  /  ;  play  $SOUND_FILE  & )
         fi
    ;;
  esac

}

query()  
{ 
#  2 arguments
#  query  "what do you want?  "  DEFAULT

  if  [  -z  "$SILENT"  ];  then

    # message  "Press y for yes, n for no."
    if  [  -n  "$MODULE"  ];  then
      echo  -e  -n  "${MODULE_COLOR}${MODULE}${DEFAULT_COLOR}:  "
      echo  -e  -n  "${QUERY_COLOR}$1 [$2] ${DEFAULT_COLOR}"
    else
      echo  -e  -n  "${QUERY_COLOR}$1 [$2] ${DEFAULT_COLOR}"
    fi

    read   -t  $PROMPT_DELAY  -n  1  RESPONSE
    echo

    RESPONSE=${RESPONSE:=$2}
    case  $RESPONSE  in
      y|Y)  true  ;;
        *)  false ;;
    esac

  else

    echo  $2
    case  $2  in
        y|Y)  true    ;;
          *)  false   ;;
    esac

  fi
}


message()    {  [  -n  "$SILENT"  ]  ||  echo  -e  "$*";  }


report() {

  if  [  ! -f  $1  ];  then  return;  fi

  if  [  "$VIEW_REPORTS"  ==  "on"  ];  then

    VIEW_PROMPT="View $2 for ${MODULE_COLOR}${MODULE}-${VERSION_COLOR}${VERSION}${DEFAULT_COLOR}?"
    sound  REPORT
    if  query  "$VIEW_PROMPT" n;  then  less  $1;  fi
  fi

  if  [  "$MAIL_REPORTS"  ==  "on"  ];  then
    MAILTEMP="/tmp/lunar.mail.`uuidgen`" 
    date  -u  > $MAILTEMP
    echo     >> $MAILTEMP
    cat $1   >> $MAILTEMP
    mail  -s  "Lunar Report from $HOSTNAME : $2 for $MODULE-$VERSION"  \
              $ADMIN  < $MAILTEMP  2>/dev/null
    rm -f $MAILTEMP 2>/dev/null          
  fi

  true

}


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


testpack() {

  FILENAME=`guess_filename                $1`  ||
  FILENAME=`guess_filename  $SOURCE_CACHE/$1`

  [  -f  $FILENAME  ]                                    &&
  COMPRESSOR=`file  -b  $FILENAME  |  cut  -d ' '  -f1`  &&
  
  case  $COMPRESSOR  in
        bzip2)  bzip2  -tf   $FILENAME   1>/dev/null 2>&1  ;;
         gzip)  gzip   -tf   $FILENAME   1>/dev/null 2>&1  ;;
    compress*)  gzip   -tf   $FILENAME   1>/dev/null 2>&1  ;;
          Zip)  unzip  -tq   $FILENAME   1>/dev/null 2>&1  ;;
          RPM)  rpmunpack  < $FILENAME   |                 \
                gzip   -t                1>/dev/null 2>&1  ;;
            *)  true                                       ;;
  esac

}


unpack() {

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

  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

    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
      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()  {

       OLD_LIBS=$SOURCE_DIRECTORY/old.libraries
          SAVED=$OLD_LIBS/$MODULE.saved.libraries
  [  -f  $SAVED  ]    &&
  cat    $SAVED       |
  while  read  FILE;  do
    rm  -f   "$FILE"    
  done

  ldconfig  $OLD_LIBS

}


prepare_install() {

  message  "${MESSAGE_COLOR}Preparing to install"  \
           "${MODULE_COLOR}${MODULE}${DEFAULT_COLOR}"

  while  boost_locked;  do
    sleep  5
  done

  echo  $$  >  $BOOST_LOCK

  if  module_installed  $MODULE   ||
      module_held       $MODULE;  then

    save_libraries
    cp -a /usr/share/info/dir /tmp/info_dir.saved
    lrm  --nosustain  $MODULE
    mv /tmp/info_dir.saved /usr/share/info/dir
    true

  fi

  rm  -f  /tmp/$MODULE.iw

}


rm_source_dir() {

  cd  /

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

  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() {

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

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

}


validate_source_dir()  {

  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() {
  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
}

# Usage: patch_it location/name level 
# Example: patch_it $SOURCE_CACHE/foo.bz2 1
patch_it() {
  if [[ `echo $1 | grep .tar` ]]; then
    if [[ `echo $1 | grep .bz2` ]]; then
      bzcat $1 | tar x -O | patch -N -p$2
    elif  [[ `echo $1 | grep .gz` ]]; then
      zcat $1 | tar x -O | patch -N -p$2
    else
      cat $1 | tar x -O | patch -N -p$2
    fi      
  else
    if [[ `echo $1 | grep .bz2` ]]; then
      bzcat $1 | patch -N -p$2
    elif [[ `echo $1 | grep .gz` ]]; then
      zcat $1 | patch -N -p$2
    else
      cat $1 | patch -N -p$2 
    fi
  fi
}

default_pre_build() {
  if [[ `echo $MODULE | grep -e -cvs` ]]; then
    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               $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() 
{
   echo CFLAGS:= $CFLAGS                   &&
   echo OPTS:= $OPTS                       &&
   set -x && #Let's show the logs what we've used for debug
   ./configure  --build=$BUILD            \
                --prefix=/usr             \
                --sysconfdir=/etc         \
                --localstatedir=/var      \
                --infodir=/usr/share/info \
                --mandir=/usr/share/man   \
                $OPTS                     &&
   set +x      ##turn it off so that the logs stay readable
} > $C_FIFO 2>&1

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

default_build() 
{
   default_config  &&
   #activate_voyeur &&   
   default_make
} > $C_FIFO 2>&1


gather_docs()  {

  DOC_DIR=$DOCUMENT_DIRECTORY/$MODULE
  mkdir  -p  $DOC_DIR
  cp         $SOURCE_DIRECTORY/README*     $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/INSTALL*    $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/FAQ*        $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/CHAN*       $DOC_DIR  2>/dev/null
  cp     -r  $SOURCE_DIRECTORY/doc*        $DOC_DIR  2>/dev/null
  cp     -r  $SOURCE_DIRECTORY/DOC*        $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/*doc        $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/*rc         $DOC_DIR  2>/dev/null
  cp     -r  $SOURCE_DIRECTORY/conf        $DOC_DIR  2>/dev/null
  cp     -r  $SOURCE_DIRECTORY/SETUP       $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/NEWS        $DOC_DIR  2>/dev/null
  cp         $SOURCE_DIRECTORY/Change*     $DOC_DIR  2>/dev/null

}


install_pam_confs()  {

  if  [  -d  "$SCRIPT_DIRECTORY/pam.d"  ];  then
    cd       "$SCRIPT_DIRECTORY/pam.d"

    [ -d /etc/pam.d ] || mkdir  -p  /etc/pam.d

    for  FILE  in  `ls`;  do
      if  !  [  -f  /etc/pam.d/$FILE  ];  then
        /usr/bin/install -g 0 -o 0 -m 600 $FILE /etc/pam.d
        cp  $FILE   /etc/pam.d
      fi
    done

  fi

}


install_xinetd_confs()  { (

  if  [  -d  "$SCRIPT_DIRECTORY/xinetd.d"  ];  then
    cd       "$SCRIPT_DIRECTORY/xinetd.d"

    [ -d /etc/xinetd.d ] || mkdir  -p  /etc/xinetd.d

    for  SERVICE  in  $SERVICES;  do
      for  FILE  in  `ls`;  do
        if    grep  -q  "service $SERVICE"   $FILE  ; then
	  if [ ! -f /etc/xinetd.d/$FILE ] ; then
            /usr/bin/install --backup=numbered -g 0 -o 0 -m 600 $FILE /etc/xinetd.d
	  fi
        fi
      done
    done

    if  [  -n  "$SERVICES"  ];  then
      devoke_installwatch
      [ ! -x /etc/init.d/xinetd ] || /etc/init.d/xinetd  restart
      invoke_installwatch
    fi
  fi

) }

install_initd()  { (

  [ -d /etc/init.d ] || mkdir -p /etc/init.d

  if  [ -d  $SCRIPT_DIRECTORY/init.d  ] ; then
    cd $SCRIPT_DIRECTORY/init.d
    SCRIPTS=$(find . -type f -maxdepth 1 )
    ALL_INITDSCRIPTS=$(grep -l "# chkconfig: " $SCRIPTS | cut -d/ -f2)

    for INITDSCRIPT in $ALL_INITDSCRIPTS; do
      if [ ! -f /etc/init.d/$INITDSCRIPT ] ; then
        /usr/bin/install -g 0 -o 0 -m 700 $SCRIPT_DIRECTORY/init.d/$INITDSCRIPT /etc/init.d/
      fi
    done
    cd $SCRIPT_DIRECTORY
  fi

  for INITDSCRIPT in $INITDSCRIPTS; do
    ls /etc/rc?.d/???$INITDSCRIPT > /dev/null 2>&1 &&
    	rm /etc/rc?.d/???$INITDSCRIPT
    chkconfig --add $INITDSCRIPT

    CHKCONFIG=`grep '^# chkconfig:' /etc/init.d/$INITDSCRIPT | cut -d : -f 2-2`
    if `echo $CHKCONFIG | grep -q $(/sbin/runlevel | cut -d ' ' -f 2-2) -`
    then
      devoke_installwatch
      ( cd / && /etc/init.d/$INITDSCRIPT stop )
      ( cd / && /etc/init.d/$INITDSCRIPT start )
      invoke_installwatch
    fi

  done

) }

install_services()  { (


  if  [  -f  $SCRIPT_DIRECTORY/services  ];  then

  export  IFS="$ENTER_IFS"

    cat  $SCRIPT_DIRECTORY/services  |
    while  read  LINE;  do
      grep  -q  "$LINE"      /etc/services  ||
      echo      "$LINE"  >>  /etc/services
    done
  fi

) }

install_bashmisc () { (

  if [ -d $SCRIPT_DIRECTORY/profile.d ]; then
    [ -d /etc/profile.d ] || mkdir -p /etc/profile.d
    install -g 0 -o 0 -m 644 $SCRIPT_DIRECTORY/profile.d/*.rc /etc/profile.d
    message "\n${MESSAGE_COLOR}Please log out and log in again to make changes in your shell\nenvironment take effect.${DEFAULT_COLOR}\n"
  fi
  if [ -d $SCRIPT_DIRECTORY/skel ]; then
    [ -d /etc/skel ] || mkdir -p /etc/skel
    cp $SCRIPT_DIRECTORY/skel/* /etc/skel &> /dev/null
    cp $SCRIPT_DIRECTORY/skel/.* /etc/skel &> /dev/null
  fi

) }

default_post_build() {

  install_pam_confs
  install_services
  install_xinetd_confs
  install_initd
  install_bashmisc
  
  if [  "$GARBAGE"  ==  "on"  ];  then
      gather_docs
  fi

  devoke_installwatch
  ldconfig
  # release_saved_libraries
  cd  /
  boost

}

module_installed() 
{

      if  grep  -q  "^$1\:"         $MODULE_STATUS 2>/dev/null ;  then
    STAT=`grep      "^$1\:"         $MODULE_STATUS 2>/dev/null   |  cut  -d : -f3`;  else
    STAT=`grep      "^$1-custom\:"  $MODULE_STATUS 2>/dev/null   |  cut  -d : -f3`
  fi
  [  "$STAT"  ==  "installed"  ]
}

module_held() {

  STAT=`grep  "^$1\:"  $MODULE_STATUS 2>/dev/null   |  cut  -d : -f3`  &&
  [  "$STAT"  ==  "held"  ]

}

module_exiled()  {

  STAT=`grep  "^$1\:"  $MODULE_STATUS 2>/dev/null   |  cut  -d : -f3`  &&
  [  "$STAT"  ==  "exiled"  ]

}


installed_version()  
{
  if    grep  -q     "^$1\:"      $MODULE_STATUS 2>/dev/null; then  
     echo  `grep  "^$1\:"         $MODULE_STATUS 2>/dev/null   |  cut  -d :  -f4`
  else  
     echo  `grep  "^$1-custom\:"  $MODULE_STATUS 2>/dev/null   |  cut  -d :  -f4`
  fi
}


# 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()
{
##  ! module_installed $MODULE && return 0

  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()  {
  remove_module  $1
  lock_file $MODULE_STATUS                                    && 
  lock_file $MODULE_STATUS_BACKUP                             &&
  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 
}


is_depends()  {  (
  #  Is $1 a previously selected dependency of any module.

  EXIT_STATUS="false"

  for  DEP  in  `cut  -d :  -f2-  $DEPENDS_STATUS  |
                 grep  "^$1:"`
  do

    DEP_STATUS=`echo  "$DEP"  |  cut  -d :  -f2`

    if    [  "$DEP_STATUS"  ==  "on"  ]
    then  EXIT_STATUS="true"
          break
    fi

  done

  $EXIT_STATUS

)  }


in_depends()  {
  #  Was $2 presented as a depenency for module $1

  if    grep  -q  "^$1:$2"  $DEPENDS_STATUS
  then  true
  else  false
  fi

}


remove_depends()  
{
  lock_file $DEPENDS_STATUS_BACKUP &&
  lock_file $DEPENDS_STATUS        ||
  return 1

  if    [  -n  "$2"  ]
  then  
     grep  -v  "^$1:$2"  $DEPENDS_STATUS_BACKUP  >  $DEPENDS_STATUS
  else  
     grep  -v  "^$1:"    $DEPENDS_STATUS_BACKUP  >  $DEPENDS_STATUS
  fi
  cat $DEPENDS_STATUS > $DEPENDS_STATUS_BACKUP
  
  unlock_file $DEPENDS_STATUS_BACKUP &&
  unlock_file $DEPENDS_STATUS
}


add_depends()  
{
  remove_depends  "$1"  "$2"

  lock_file $DEPENDS_STATUS_BACKUP                       &&
  lock_file $DEPENDS_STATUS                              &&
  echo  "$1:$2:$3:$4:$5:$6"  >>  $DEPENDS_STATUS         &&
  cat  $DEPENDS_STATUS        >  $DEPENDS_STATUS_BACKUP  &&
  unlock_file $DEPENDS_STATUS_BACKUP                     &&
  unlock_file $DEPENDS_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"
    
}


run_depends() {

  # local definitions of depends and optional_depends!
  depends()  {
    grep -q "^"$1"\$" $PREPD 2>/dev/null && return 0
    if  ! module_installed  $1   &&
        ! module_held       $1 
    then
      if  !  is_depends     $1   &&
             module_exiled  $1 
      then  return  1
      else
        message "${MODULE_COLOR}${MODULE}: ${DEFAULT_COLOR}" \
                "Adding required dependency${FILE_COLOR}"   \
                "$1 ${DEFAULT_COLOR}"
        lin  --deps  $1
        echo "$1" >> $PREPD
      fi
    fi
    add_depends  "$MODULE"  "$1"  "on"  "required"  "$2"  "$3"
  }

  optional_depends()  {

    # parameters:  $1 = module name
    #              $2 = configure parameter if module wanted
    #              $3 = configure parameter if module declined
    #              $4 = description of why to use this module.


    if  !  in_depends  "$MODULE"  "$1";  then

      if    module_exiled  $1
      then  add_depends  "$MODULE"  "$1"  "off"  "optional"  "$2"  "$3"
      else

        if  module_installed  $1  ||
            module_held       $1
        then  DEFAULT="y"
        else  DEFAULT="n"
        fi

        if    is_depends  $1  ||
              query  "Install optional dependency $1 $4? " $DEFAULT
        then  lin  --deps  $1
              add_depends  "$MODULE"  "$1"  "on"   "optional"  "$2"  "$3"
        else  add_depends  "$MODULE"  "$1"  "off"  "optional"  "$2"  "$3"
        fi
      fi
    fi

  }

  prepare_depends_status
  grep -q "^"$MODULE"\$" $PREPD 2>/dev/null && return 0
  if  [  -x  $SCRIPT_DIRECTORY/DEPENDS  ];  then
    message  "${CHECK_COLOR}Checking dependencies for"  \
             "${MODULE_COLOR}${MODULE}"                   \
             "${DEFAULT_COLOR}"
    . $SCRIPT_DIRECTORY/DEPENDS
  fi
}

# 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 ; then
      
        message
        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
          echo
          sleep 3         
          continue
	else
	  message "${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} is kept and can be removed manually later${DEFAULT_COLOR}"
	  echo
	  sleep 3
	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 :  lvu  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
) }

# function : satisfy_depends
# usage    : satisfy_depends (operates on $MODULE variable)
# purpose  : re-check module deps based on DEPENDS_CONFIG and DEPENDS_STATUS
satisfy_depends()  {

  [ -n "$DEPS_ONLY" ] && return 0      
  unset  OPTS  
  MODULE_CONFIG=$DEPENDS_CONFIG/$MODULE
    
  if  [  -s  $MODULE_CONFIG  ];  then
          .  $MODULE_CONFIG
  fi

  TMP_FILE="/tmp/satisfy_depends.`uuidgen`"
  grep  "^$MODULE:"  $DEPENDS_STATUS > $TMP_FILE

  while read LINE; do
    DEP_MODULE=`echo  $LINE  |  cut  -d :  -f2`
    DEP_STATUS=`echo  $LINE  |  cut  -d :  -f3`
        DEP_ON=`echo  $LINE  |  cut  -d :  -f5`
       DEP_OFF=`echo  $LINE  |  cut  -d :  -f6`

    if  [  -n  "$FIX"  ]
    then  if  DEP_STATUS="on"
          then  lin  $FIX  $DEP_MODULE
          fi
    elif  [  "$DEP_STATUS"  ==  "off"  ]  ||
          module_exiled  $DEP_MODULE
    then  OPTS="$OPTS  $DEP_OFF"

    elif  [  "$DEP_STATUS"  ==  "on"  ]   &&
          !  module_installed  $DEP_MODULE  &&
          !  module_held       $DEP_MODULE
    then
      if    lin  $SILENT  $COMPILE  $DEP_MODULE
      then  OPTS="$OPTS  $DEP_ON"
      else  exit  1
      fi
    else  OPTS="$OPTS  $DEP_ON"
    fi

  done < $TMP_FILE

  rm $TMP_FILE 2> /dev/null

}


color()  {

  case  $1  in
    off)  unset  MODULE_COLOR
          unset  VERSION_COLOR
          unset  QUERY_COLOR
          unset  LRM_COLOR
          unset  CHECK_COLOR
          unset  RESURRECT_COLOR
          unset  FILE_COLOR
          unset  SYMLINK_COLOR
          unset  PROBLEM_COLOR
          unset  MESSAGE_COLOR
          unset  DEFAULT_COLOR
          COLOR=off
          ;;
     on)  COLOR=on
          ;;
  esac

}


invoke_installwatch()  {

  if  [  -e  /usr/lib/installwatch.so  ];  then
    if [ -z "$INSTALLWATCHFILE" ] ; then
      rm  -rf  /tmp/$MODULE.iw
    fi
    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

  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  -rf  $CACHE
  rm  -rf  $INST_LOG
  touch    $INST_LOG
  rm  -rf  $TMP_LOG
  rm  -rf  $MD5_LOG
  touch    $MD5_LOG

  track    &&
  archive  &&
#find_module_size is in functions/sizes
  add_module  $MODULE installed $VERSION `find_module_size $MODULE $VERSION`

) }


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
  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
  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
  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
  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
  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`;  }
handle_depends()  {  true;  }

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
}


# get_moonbase ()
# function: get_moonbase
# usage   : get_moonbase
# purpose : fetches a fresh moonbase from lunar-linux.org/lunar and install it
get_moonbase() {
  # we could variableize this too:
  MODULE=moonbase
  VERSION=`date -u +%Y%m%d`
  SOURCE=${MODULE}-${VERSION}.tar.bz2

  # initialize the dirs in case of goof-up
  [ ! -d /var/lib/lunar/moonbase ] &&
    mkdir -p /var/lib/lunar/moonbase
  [ ! -d /var/lib/lunar/moonbase/zlocal ] &&
    mkdir -p /var/lib/lunar/moonbase/zlocal

  echo -e "${MESSAGE_COLOR}Downloading ${FILE_COLOR}${SOURCE}" \
          "${DEFAULT_COLOR}${MESSAGE_COLOR}...${DEFAULT_COLOR}"
   wget -O /tmp/$SOURCE $MOONBASE_URL \
     $RATE $FTP_CONNECTION $RETRIES $PARTIAL                        &&
  echo -e "${MESSAGE_COLOR}Preparing to install ${FILE_COLOR}${SOURCE}" \
          "${DEFAULT_COLOR}${MESSAGE_COLOR}...${DEFAULT_COLOR}"     &&
  mv /tmp/$SOURCE $SOURCE_CACHE/$SOURCE                             &&

  # here we clean up our moonbase while we're at it!
  mv /var/lib/lunar/moonbase/zlocal /var/lib/lunar/.zlocal-backup   &&
  rm -rf /var/lib/lunar/moonbase                                    &&
  mkdir /var/lib/lunar/moonbase                                     &&
  mv /var/lib/lunar/.zlocal-backup /var/lib/lunar/moonbase/zlocal   &&
  
  echo -e "${MESSAGE_COLOR}Extracting ${FILE_COLOR}${SOURCE}"       \
          "${DEFAULT_COLOR}${MESSAGE_COLOR}...${DEFAULT_COLOR}"     &&
  
  bzcat $SOURCE_CACHE/$SOURCE | tar x -C /var/lib/lunar             &&
  OUTCOME=success || OUTCOME=failed
  
  rm -f $SOURCE_CACHE/$SOURCE
  message  "${MESSAGE_COLOR}Removed ${FILE_COLOR}${SOURCE}${DEFAULT_COLOR}"

  echo -e "${MESSAGE_COLOR}Creating ${FILE_COLOR}${MODULE_INDEX}" \
    	    "${DEFAULT_COLOR}${MESSAGE_COLOR}...${DEFAULT_COLOR}"
  if [ -f $MODULE_INDEX ]; then
    rm $MODULE_INDEX                 
  fi
  create_module_index
  
  activity_log "lin" "moonbase" "$VERSION" "$OUTCOME" "$INFO"

}


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


# rework_module : check depends database for a module
rework_module() {

  # we declare these local to override the systems default ones:
  optional_depends()  {
    if    module_exiled  $1
    then  add_depends  "$MODULE"  "$1"  "off"  "optional"  "$2"  "$3"
    else
      if  module_installed  $1  ||
          module_held       $1
      then  add_depends  "$MODULE"  "$1"  "on"   "optional"  "$2"  "$3"
      else  add_depends  "$MODULE"  "$1"  "off"  "optional"  "$2"  "$3"
      fi
    fi
  }

  depends()  {  
    if  ! module_installed  $1   &&
        ! module_held       $1
    then
      if  !  is_depends     $1   &&
             module_exiled  $1
      then  return  1
      else
        echo -e "${MODULE_COLOR}${MODULE}${DEFAULT_COLOR}${MESSAGE_COLOR} is missing ${MODULE_COLOR}$1${DEFAULT_COLOR}"
	CHANGED_MODULES="$CHANGED_MODULES $1"
      fi  
    fi
    add_depends  "$MODULE"  "$1"  "on"  "required"  "$2"  "$3"
  } 

  run_depends() {
    if  [  -x  $SCRIPT_DIRECTORY/DEPENDS  ];  then
      show_fancy_progress "Processing: $MODULE"
      . $SCRIPT_DIRECTORY/DEPENDS
    fi
  }

  # here starts the real work:
  MODULE=$1

  # base vars needed to execute DEPENDS
  SECTION=$(find_section $MODULE)
  SCRIPT_DIRECTORY=$MOONBASE/$SECTION/$MODULE
  MODULE_CONFIG=$CONFIG_CACHE/depends/$MODULE

  # reroute depends output to our private files:
  OLD_DEPENDS_STATUS=$DEPENDS_STATUS
  OLD_DEPENDS_STATUS_BACKUP=$DEPENDS_STATUS_BACKUP
      
  DEPENDS_STATUS=$TMP/depends
  DEPENDS_STATUS_BACKUP=$TMP/depends.backup
  touch $DEPENDS_STATUS
  touch $DEPENDS_STATUS_BACKUP

  # fetch old depend data:
  grep "^$MODULE:" $OLD_DEPENDS_STATUS | sort | uniq > $TMP/depends.old.$MODULE

  # fetch new depend data:
  run_depends
  grep "^$MODULE:" $DEPENDS_STATUS | sort | uniq > $TMP/depends.new.$MODULE
  
  if $(! diff -q $TMP/depends.old.$MODULE $TMP/depends.new.$MODULE &> /dev/null ) ; then
    echo -e "${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} has changed depends:${DEFAULT_COLOR}"
    CHANGED_MODULES="$CHANGED_MODULES $MODULE"
    LIST=$(cat $TMP/depends.old.$MODULE $TMP/depends.new.$MODULE | cut -d: -f2 | sort | uniq )
    for DEP in $LIST; do
      OLDDEP=$(grep ":$DEP:" $TMP/depends.old.$MODULE)
      NEWDEP=$(grep ":$DEP:" $TMP/depends.new.$MODULE)
      if [ "$OLDDEP" != "$NEWDEP" ] ; then

        # diff style output for debugging:
        # echo "- $OLDDEP"
	# echo "+ $NEWDEP"
	
	# the tricky part is deciding what is necessary and what not:
	OLD_STATUS=$(echo $OLDDEP | cut -d: -f3)
	NEW_STATUS=$(echo $NEWDEP | cut -d: -f3)
	OLD_REQD=$(echo $OLDDEP | cut -d: -f4)
	NEW_REQD=$(echo $NEWDEP | cut -d: -f4)
	OLD_ON_OPTS=$(echo $OLDDEP | cut -d: -f5)
	NEW_ON_OPTS=$(echo $NEWDEP | cut -d: -f5)
	OLD_OFF_OPTS=$(echo $OLDDEP | cut -d: -f6)
	NEW_OFF_OPTS=$(echo $NEWDEP | cut -d: -f6)
	if [ -z "$NEWDEP" ] ; then
	  echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was removed from the dependancy list${DEFAULT_COLOR}"
	else
	  if [ -z "$OLDDEP" ] ; then
	    echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was added to the $NEW_REQD dependancy list${DEFAULT_COLOR}"
	  else
            # the dep changed!
	    if [ "$OLD_STATUS" == "on" -a "$NEW_STATUS" == "on" ]; then
	      if [ "$OLD_REQD" == "required" -a "$NEW_REQD" == "optional" ]
	      then
		echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was changed to optional${DEFAULT_COLOR}"
	      elif [ "$OLD_REQD" == "optional" -a "$NEW_REQD" == "required" ]
	      then
	        echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was changed to required${DEFAULT_COLOR}"
	      else
	        echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} has new compile flags for ${MODULE_COLOR}$DEP${MESSAGE_COLOR}${DEFAULT_COLOR}"
	      fi
	    elif [ "$OLD_STATUS" == "off" -a "$NEW_STATUS" == "off" ]; then
              if [ "$OLD_REQD" == "required" -a "$NEW_REQD" == "optional" ]
	      then
	        echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was changed to optional${DEFAULT_COLOR}"
	      elif [ "$OLD_REQD" == "optional" -a "$NEW_REQD" == "required" ]
	      then
	        echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was changed to required${DEFAULT_COLOR}"
	      else
	        echo -e "${MESSAGE_COLOR}* ${MODULE_COLOR}$MODULE${DEFAULT_COLOR}${MESSAGE_COLOR} has new compile flags for ${MODULE_COLOR}$DEP${MESSAGE_COLOR}${DEFAULT_COLOR}"
	      fi
	    elif [ "$OLD_STATUS" == "off" -a "$NEW_STATUS" == "on" ]; then
	      echo -e "${MESSAGE_COLOR}* $NEW_REQD ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was installed${DEFAULT_COLOR}"
	    elif [ "$OLD_STATUS" == "on" -a "$NEW_STATUS" == "off" ]; then
	      echo -e "${MESSAGE_COLOR}* $NEW_REQD ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} was removed${DEFAULT_COLOR}"
	    else
	      echo -e "${$MESSAGE_COLOR}* ${MODULE_COLOR}$DEP${DEFAULT_COLOR}${MESSAGE_COLOR} ${PROBLEM_COLOR}missed exception $OLD_STATUS $NEW_STATUS${DEFAULT_COLOR}"
	    fi
	  fi
	fi
      fi
    done
  fi

  # clean up
  rm $DEPENDS_STATUS
  rm $DEPENDS_STATUS_BACKUP
  DEPENDS_STATUS=$OLD_DEPENDS_STATUS
  DEPENDS_STATUS_BACKUP=$OLD_DEPENDS_STATUS_BACKUP   

}

# rework_list : rework a list of modules and save output
rework_list() {

  for MODULE in $* ; do
    module_exiled $MODULE || rework_module $MODULE
  done

}

# fix_depends : single pass to fix depends database
fix_depends () {

  TMP=/tmp/lunar.fix
  [ -d $TMP ] || mkdir -p $TMP

  CHANGED_MODULES=
  # we NEED this
  if [ -f "$INSTALL_QUEUE" ] ; then
    rm $INSTALL_QUEUE
    touch $INSTALL_QUEUE
  fi
  
  if [ -n "$1" ] ; then
    rework_list $*
  else
    rework_list $(cat $MODULE_STATUS | cut -d: -f1 | sort )
  fi

  if [ -n "$CHANGED_MODULES" ] ; then

    for MODULE in $CHANGED_MODULES ; do
      if [ ! -e $TMP/depends.new.$MODULE ] ; then
        rework_module $MODULE
      fi
    done
    
    # this ensures the bastard doesn't recheck it:
    if [ -z "$NOFIX" ] ; then
      mv $DEPENDS_STATUS $TMP/depends
      cp $TMP/depends $TMP/depends.filter
      for MODULE in $CHANGED_MODULES ; do
        grep -v "^$MODULE:" $TMP/depends.filter > $TMP/depends.filter~
        mv $TMP/depends.filter~ $TMP/depends.filter
      done
      mv $TMP/depends.filter $DEPENDS_STATUS 
      cat $TMP/depends.new.* >> $DEPENDS_STATUS
      cp $DEPENDS_STATUS $DEPENDS_STATUS_BACKUP
    fi

    OLD_FIX=$FIX
    unset FIX
    OLD_lin_PASS=$lin_PASS; export lin_PASS=three

    for MODULE in $CHANGED_MODULES ; do
      if [ -n "$FIXDEPENDS" ] ; then
        # special case: when called with --fixdepends, skip recompile!
	cp $TMP/depends $TMP/depends.filter
	for MODULE in $CHANGED_MODULES ; do
	  grep -v "^$MODULE:" $TMP/depends.filter > $TMP/depends.filter~
	  mv $TMP/depends.filter~ $TMP/depends.filter
	done
        mv $TMP/depends.filter $DEPENDS_STATUS
	cat $TMP/depends.new.* >> $DEPENDS_STATUS
	cp $DEPENDS_STATUS $DEPENDS_STATUS_BACKUP
      else
        if [ -z "$NOFIX" ] ; then
          if ! lin -c $MODULE ; then
	    # put back the faulty depends so we know fixing this failed
	    # and will be found again on the next run
	    cat $TMP/depends > $DEPENDS_STATUS
	    cp $DEPENDS_STATUS $DEPENDS_STATUS_BACKUP
          else
	    # sometimes after lin all depends are gone! force it down it's throat
            cp $TMP/depends $TMP/depends.filter
            for MODULE in $CHANGED_MODULES ; do
              grep -v "^$MODULE:" $TMP/depends.filter > $TMP/depends.filter~
              mv $TMP/depends.filter~ $TMP/depends.filter
            done
            mv $TMP/depends.filter $DEPENDS_STATUS 
            cat $TMP/depends.new.* >> $DEPENDS_STATUS
            cp $DEPENDS_STATUS $DEPENDS_STATUS_BACKUP
	  fi
	fi
      fi
      remove_queue $INSTALL_QUEUE $MODULE
    done
    
    FIX=$OLD_FIX
    unset OLD_FIX
    export lin_PASS=$OLD_lin_PASS

  fi

  rm -rf $TMP

}


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