#! /bin/sh
# Package Create  -  @2000 by Antonio Gallo
# agx@linux.it - www.badpenguin.org - www.linux.it/~agx
# 20 May 2000, This script is used to help a mantainer to create
#              a package to be used on Bad Penguin.
# Requirements: awk, cat, du, grep
# Mon Jul 17 20:58:43 2000, can build packages without source
# Mon Aug 21 23:07:05 2000, contribution from Biagio Lucini

##### =====================      tools    =========================  #####

ask () {
  echo "----------------------------------------------------------------------"
  color PURPLE
  echo -e "? $2"
  if [ "$1" = "" ]; then
    echo -n ": "
  else
    echo -n -e "  ($1): "
  fi
  color WHITE
}

require() {
  if [ "$2" = "" ]; then
    echoc RED "! nothing was specified for '$1', giving up."
    exit 1
  fi
}

askfile() {
  [ "$PKGMODE" != "create" ] && return
  echo "----------------------------------------------------------------------"
  echoc PURPLE "? `basename $1` ($2) press ENTER to skip or type 'edit'"
  if [ ! -f "$1" ]; then
    echoc PURPLE -n ": "
  else
    color PUPLR
    echo -n "  ("
    cat $1 | grep -v "^$"
    echo -n "): "
    color WHITE
  fi
  read x
  if [ "$x" != "" ] ; then
    if [ ! -f "$1" -o -z "$1" ]; then
      echo -e "#!/bin/sh\nset -e\n$2\n" > $1
    fi
    edit $1
    echo "- editing of $1 done"
  fi
}

fn_read_settings() {
  echo "- reading global settings"
  if [ ! -f "$DIST_VERSION" ]; then
    echoc RED "! Global file $DIST_VERSION not found"
    exit 1
  fi
  . $DIST_VERSION
  DISTRELEASE="$NAME $VERSION"
  echo "- distribution $DISTRELEASE"
  # Clean up version because it conflicts with the package version in INFO
  VERSION=""
  # read main BPP option file
  if [ ! -f "$PACKAGE_CONF" ]; then
    echoc RED "! global file $PACKAGE_CONF not found"
    exit 1
  fi
  echo "- reading package conf"
  . "$PACKAGE_CONF"
}

fn_read_info() { 
  if [ ! -f "$PKGINFO" ]; then
    echoc RED "- PKGINFO does not exists"
    exit
  fi
  echo "- reading package INFO"
  # Set Default Values
  COPYRIGHT="GPL"
  DISKNAME="1"
  DISKUSAGE=0
  STATUS="UNSTABLE"
  OSNAME="`uname -s`"
  OSVERSION="`uname -r`"
  ARCH="i386"
  OPTIM="`uname -m`"
  DISTRIBUTION="$DISTRELEASE"
  BUILDHOST="`hostname`.`domainname`"
  BUILDTIME="`date`"
  BUILDNUMBER=0
  BPPVERSION="$PKG_VERSION"
  # Read
  . "$PKGINFO"
  FULLVERSION="${SONAME}_${VERSION}"
}

fn_write_info() {
  echoc GREEN "- Updating package infoes"
  > "$PKGINFO"
  echo "# Global"			>>"$PKGINFO"
  echo "SONAME=$SONAME"			>>"$PKGINFO"
  echo "VERSION=\"$VERSION\""		>>"$PKGINFO"
  echo "CATEGORY=$CATEGORY"		>>"$PKGINFO"
  echo "ARCH=$ARCH"			>>"$PKGINFO"
  echo "OPTIM=$OPTIM"			>>"$PKGINFO"
  echo "# Credits"			>>"$PKGINFO"
  echo "SUMMARY=\"$SUMMARY\""		>>"$PKGINFO"
  echo "AUTHOR=\"$AUTHOR\""		>>"$PKGINFO"
  echo "COPYRIGHT=\"$COPYRIGHT\""	>>"$PKGINFO"
  echo "MANTAINER=\"$MANTAINER\""	>>"$PKGINFO"
  echo "HOMEPAGE=$HOMEPAGE"		>>"$PKGINFO"
  echo "# Distrib"			>>"$PKGINFO"
  echo "DISKNAME=$DISKNAME"		>>"$PKGINFO"
  echo "DISKUSAGE=$DISKUSAGE"		>>"$PKGINFO"
  echo "STATUS=$STATUS"			>>"$PKGINFO"
  echo "# Build Info"			>>"$PKGINFO"
  echo "OSNAME=$OSNAME"			>>"$PKGINFO"
  echo "OSVERSION=\"$OSVERSION\""	>>"$PKGINFO"  
  echo "DISTRIBUTION=\"$DISTRIBUTION\""	>>"$PKGINFO"
  echo "BUILDHOST=$BUILDHOST"		>>"$PKGINFO"
  echo "BUILDTIME=\"$BUILDTIME\""	>>"$PKGINFO"
  echo "BUILDNUMBER=$BUILDNUMBER"	>>"$PKGINFO"
  echo "BPPVERSION=\"$BPPVERSION\""	>>"$PKGINFO"
  echo "# Checks"			>>"$PKGINFO"
  echo "CONFLICTS=\"$CONFLICTS\""	>>"$PKGINFO"
  echo "DISKUSAGES=\"$DISKUSAGES\""	>>"$PKGINFO"
  echo "REQUEST=\"$REQUEST\""		>>"$PKGINFO"
  echo "# Build Info"			>>"$PKGINFO"
  echo "SOURCEFILES=\"$SOURCEFILES\""	>>"$PKGINFO"
  echo "SOURCEMIRRORS=\"$SOURCEMIRRORS\"" >>"$PKGINFO"
  #echo "SOURCEDIR=$SOURCEDIR"		>>"$PKGINFO"
  echo "PATCHFILES=\"$PATCHFILES\""	>>"$PKGINFO"
  echo "PATCHMIRRORS=\"$PATCHMIRRORS\""	>>"$PKGINFO"
  echo "SOURCEREQUEST=\"$SOURCEREQUEST\"" >>"$PKGINFO"
}

fn_run_script() {
  [ ! -f $1 ] && return 1
  [ ! -x $1 ] && chmod 700 $1
  echoc GREEN "> running script $1"
  OLDPWD="$PWD"
  if [ "$2" != "" ] ; then
    cd $2
  fi
  #TODO: if it does not inherit shell variables please use EXPORT !!!
  $1
  REPLY=$?
  set +e  
  cd $OLDPWD
  if [ $REPLY -ne 0 ]; then
    echoc RED "! $1 has returned error nr. $REPLY"
    exit 1
  fi
  return 0
}

##### =====================   fn_package_help   =========================  #####

fn_package_banner() {
  # Announce
  if [ $SHOW_BANNER -eq 0 ]; then
    echo "----------------------------------------------------------------------"
    echoc CYAN	"Bad Penguin - Package Create 2.0.0"
    echo "----------------------------------------------------------------------"
    SHOW_BANNER=1
  else
    echo "======================================================================"
  fi
}

fn_package_help() {
  fn_package_banner
  echo
  echo -n "Usage: "
  echoc GREEN "package-create <package-temp-dir> [options]"
  echo
  echo "If you specify any options you can resume the building"
  echo "of the package to a specific steps. Do not specify any"
  echo "options normally."
  echo
  echo "Options (into execution order):"
  echo "- info,          set package's basic informations"
  echo "- sourcerequest, install packages required to build the source"
  echo "- sourceinfo,    set package's source informations"
  echo "- fetch,         download the tarballs and patches"
  echo "- checksum,      check for checksum of downloaded files"
  echo "- extract,       extract the source to a tempirary directory"
  echo "- patch,         apply patches to the extracted source"
  echo "- configure,     configure the source before to build"
  echo "- compile,        compile the source"
  echo "- install,       install the compiled source"
  echo "- scan,          scan the filesystem to find modified files"
  echo "- pack,          copy scanned files from the filesystem"
  echo "- check,         check files inside the package"
  echo "- request,       build the dependencies"
  echo "- build,         build the package"
  echo "- announce,      announce, after hard testing, a package"
  echo
  exit 1
}

##### =====================   fn_package_info          =========================  #####

fn_package_info() {
  fn_package_banner
  echoc CYAN "(1) Package info"

  # PKGINFO should exist
  if [ ! -f "$PKGINFO" ]; then
    if [ "$PKGMODE" = "create" ]; then
      echo "> creating INFO file"
      mkdir -p `dirname $PKGINFO`
      >$PKGINFO
    else
      echoc RED "! package INFO file does not exist"
      exit 1
    fi
  fi

  # Read IT
  fn_read_info
  
  # return if not in create mode
  [ "$PKGMODE" != "create" ] && return

  # prepare 'create' environment 
  if [ ! -d "$PKGROOT" ]; then
    echoc YELLOW "> creating directory $PKGROOT"
    mkdir -p -m 750 "$PKGROOT"
  fi
  if [ ! -d "$PKGROOT" ]; then
    echoc RED "! cannot create $PKGROOT"
    exit 1
  fi
  if [ ! -d "$PKGINST" ]; then
    echoc YELLOW "> creating directory $PKGINST"
    mkdir -p -m 750 "$PKGINST"
  fi
  if [ ! -d "$PKGINST" ]; then
    echoc RED "! cannot create $PKGINST"
    exit 1
  fi
  if [ ! -d "$PKGCOMPILE" ]; then
    echoc YELLOW "> creating directory $PKGCOMPILE"
    mkdir -p -m 700 "$PKGCOMPILE"
  fi
  if [ ! -d "$PKGCOMPILE" ]; then
    echoc RED "! cannot create $PKGCOMPILE"
    exit 1
  fi

  # SONAME
  ask  "$SONAME"  "enter the package SONAME without any version number"
  read XSONAME
  [ "$XSONAME" != "" ] && SONAME="$XSONAME"
  require "SONAME" "$SONAME"

  # VERSION
  ask  "$VERSION"  "enter the complete package's VERSION number"
  read XVERSION
  [ "$XVERSION" != "" ] && VERSION="$XVERSION"
  require "VERSION" "$VERSION"

  # CONFLICTS
  SUGGESTION="${SONAME}_`echo $VERSION | cut -f 1 -d'.'`"
  ask  "$CONFLICTS"  "enter the complete CONFLICTS line. suggested $SUGGESTION"
  read XCONFLICTS
  [ "$XCONFLICTS" != "" ] && CONFLICTS="$XCONFLICTS"

  # CATEGORY
  ask "$PKG_CATEGORIES" "enter the package CATEGORY from this list"
  read XCATEGORY
  [ "$XCATEGORY" != "" ] && CATEGORY="$XCATEGORY"
  require "CATEGORY" "$CATEGORY"
  #<lucini> - check category
  CHECKVAR=0
  for CATEGORYCHECK in $PKG_CATEGORIES; do
   if [ "$CATEGORY" = "$CATEGORYCHECK" ]; then
    CHECKVAR=1
   fi
  done
  if [ $CHECKVAR -eq 0 ]; then
    echoc RED "! Invalid category, giving up."
    exit 1
  fi
  #</lucini>

  # SUMMARY
  ask  "$SUMMARY"  "enter a brief summary at least 50 chars"
  read XSUMMARY
  [ "$XSUMMARY" != "" ] && SUMMARY="$XSUMMARY"

  # COPYRIGHT
  ask "$COPYRIGHT" "enter the License of this software"
  read XCOPYRIGHT
  [ "$XCOPYRIGHT" != "" ] && COPYRIGHT="$XCOPYRIGHT"
  
  # AUTHOR
  ask  "$AUTHOR"  "enter the AUTHOR of this software"
  read XAUTHOR
  [ "$XAUTHOR" != "" ] && AUTHOR="$XAUTHOR"  
  
  # HOMEPAGE
  ask "$HOMEPAGE"  "enter the HOMEPAGE of this software"
  read XHOMEPAGE
  [ "$XHOMEPAGE" != "" ] && HOMEPAGE="$XHOMEPAGE"
  
  # ARCH
  ask "$ARCH" "enter the ARCHitecture of this package, use 'i386' or 'ANY'"
  read XARCH
  [ "$XARCH" != "" ] && ARCH="$XARCH"
  require "ARCH" "$ARCH"
    
  # OPTIM
  ask  "$OPTIM"  "enter the OPTIMized arch. of this package, use 'i386' or 'ANY'"
  read XOPTIM
  [ "$XOPTIM" != "" ] && OPTIM="$XOPTIM"  
  require "OPTIM" "$OPTIM"
  
  # MANTAINER
  ask "$MANTAINER"  "enter the MANTAINER of this package"
  read XMANTAINER
  [ "$XMANTAINER" != "" ] && MANTAINER="$XMANTAINER"
  require "MANTAINER" "$MANTAINER"
    
  # Save changes
  fn_write_info
  
  # read DESCRIPTION
  if [ ! -f "$PKGINST/DESCRIPTION" ]; then
    > "$PKGINST/DESCRIPTION"
  fi
  if [ -z "$PKGINST/DESCRIPTION" ]; then
    ask "press ENTER to edit the file with a full description of this package"
    read x
    edit "$PKGINST/DESCRIPTION"
  else
    ask "" "type 'edit' to to edit the full description of this package"
    read x
    [ "$x" = "edit" ] && edit "$PKGINST/DESCRIPTION"
  fi
  echo "- DESCRIPTION done."

  # Next Step
  echo "2" >"$PKGSTEP"
  PKGLEVEL=2
}

##### =====================   fn_package_sourcerequest =========================  #####

fn_package_sourcerequest() {
  fn_package_banner
  echoc CYAN "(2) source package's request"
  fn_read_info

  # Create
  if [ "$PKGMODE" = "create" ]; then
    # SOURCEREQUEST
    ask  "$SOURCEREQUEST"  "enter the list of packages needed to build this source"
    read XSOURCEREQUEST
    if [ "$XSOURCEREQUEST" != "" ]; then
      SOURCEREQUEST="$XSOURCEREQUEST"
      fn_write_info
    fi
  fi
  
  # Check
  if [ "$SOURCEREQUEST" = "" ]; then
    echoc GREEN "- no packages are required in order to build this source"
    return
  fi
  
  # Install requests
  for i in $SOURCEREQUEST ; do
    package-setup --request $i /
  done
  
  # Next Level
  echo "3" >"$PKGSTEP"
  PKGLEVEL=3
}

##### =====================   fn_package_sourceinfo    =========================  #####

fn_package_sourceinfo() {
  fn_package_banner
  echoc CYAN "(3) source package's info"
  fn_read_info

  # return if not in create mode
  [ "$PKGMODE" != "create" ] && return

  # SOURCEFILES
  ask "$SOURCEFILES" "enter the list of tarball to download, some sources available\n\
: `cd ${PKG_SRCDEPOT}
   for i in *.gz *.bz2 ; do
     if [ -f $i ]; then
      echo -n \"$i     \"
     fi
   done`"
  read XSOURCEFILES
  [ "$XSOURCEFILES" != "" ] && SOURCEFILES="$XSOURCEFILES"
  if [ "$SOURCEFILES" != "" ]; then
    for i in $SOURCEFILES; do
      if [ ! -f "$PKG_SRCDEPOT/$i" ]; then
        echoc YELLOW "- the source file $i is not in ${PKG_SRCDEPOT}"
        exit 1
      fi
    done
  fi

  # SOURCEMIRRORS
  if [ "$SOURCEFILES" != "" ]; then
    ask "$SOURCEMIRRORS"  "enter the list of mirrors for the source\n\
  or enter one of the following pre-defined list\n\
: `cd $SOURCE_DEPOTS
   for i in * ; do
     if [ -f $i ]; then
      echo -n \"$i     \"
     fi
   done`"
    read XSOURCEMIRRORS
    [ "$XSOURCEMIRRORS" != "" ] && SOURCEMIRRORS="$XSOURCEMIRRORS"
    require "SOURCEMIRRORS"  "$SOURCEMIRRORS"
  fi

  # PATCHFILES
  ask "$PATCHFILES" "enter the list of patches to download\n\
: `cd ${PKG_SRCDEPOT}
   for i in *diff* ; do
     if [ -f $i ]; then
      echo -n \"$i     \"
     fi
   done`"
  read XPATCHFILES
  [ "$XPATCHFILES" != "" ] && PATCHFILES="$XPATCHFILES"
  if [ "$PATCHFILES" != "" ]; then
    for i in $PATCHFILES; do
      if [ ! -f "$PKG_SRCDEPOT/$i" ]; then
        echoc YELLOW "- the source file $i is not in ${PKG_SRCDEPOT}"
        exit 1
      fi
    done
  fi

  # PATCHMIRRORS
  if [ "$PATCHFILES" != "" ]; then
    ask "$PATCHMIRRORS"  "enter the list of mirrors for the PATCH\n\
  or enter one of the following pre-defined list\n\
: `cd $SOURCE_DEPOTS
   for i in * ; do
     if [ -f $i ]; then
      echo -n \"$i     \"
     fi
   done`"
    read XPATCHMIRRORS
    [ "$XPATCHMIRRORS" != "" ] && PATCHMIRRORS="$XPATCHMIRRORS"
    require "PATCHMIRRORS"  "$PATCHMIRRORS"
  fi

  # save data
  fn_write_info
    
  # Next Level
  echo "4" >"$PKGSTEP"
  PKGLEVEL=4
}

##### =====================   fn_package_fetch         =========================  #####

fn_fetch_file() {
  TARBALL="$1"
  for j in $SOURCEMIRRORS ; do
    REMOTEFILE="$SOURCEMIRRORS/$TARBALL"
    echo "- attempt to download $REMOTEFILE"
    ( cd $PKG_SRCDEPOT ; ncftp $REMOTEFILE )
    REPLY=$?
    if [ $REPLY -eq 0 ]; then
      echoc GREEN "- tarball $REMOTEFILE has been downloaded."
      break
    else
      echoc YELLOW "- tarball $REMOTEFILE has not been downloaded ($REPLY)."
    fi
  done
  # Check if tarball is really there
  if [ ! -f "$PKG_SRCDEPOT/$TARBALL" ]; then
    echoc RED "tarball $TARBALL was not found on the internet"
    exit 1
  fi
}

fn_package_fetch() {
  fn_package_banner
  echoc CYAN "(4) fetch packages and patches"
  fn_read_info

  # Check if there is some source to fetch
  if [ "$SOURCEFILES" = "" ]; then
    echoc GREEN "- no tarballs needs to be downloaded"
  else
    for i in $SOURCEFILES ; do
      if [ -f "$PKG_SRCDEPOT/$i" ]; then
        echoc GREEN "- tarball $i is already there"
      else
        echoc YELLOW "- tarball $i was not found locally"
        fn_fetch_file $i
      fi
    done
  fi
  
  # Patches
  if [ "$PATCHFILES" = "" ]; then
    echoc GREEN "- no patches needs to be downloaded"
    for i in $PATCHFILES ; do
      if [ -f $PKG_SRCDEPOT/$i ]; then
        echoc GREEN "- patch $i is already there"
      else
        echoc YELLOW "- patch $i was not found locally"
        fn_fetch_file $i      
      fi
    done
  fi

  # Next Level
  echo "5" >"$PKGSTEP"
  PKGLEVEL=5
}

##### =====================   fn_package_checksum      =========================  #####

fn_package_checksum() {
  fn_package_banner
  echoc CYAN "(5) package's checksums"
  fn_read_info

  # Check if there is something to be checked
  TEMPFILE="$PKGCOMPILE/CHECKSUMS"
  if [ ! -f $TEMPFILE ]; then

    # Anything to check ?
    if [ "$SOURCEFILES$PATCHFILES" = "" ]; then
      echoc GREEN "- there is no sources to be checked"
      return
    fi

    # Creating the file
    if [ "$PKGMODE" != "create" ]; then
      echoc RED "! there is not CHECKSUMS file into the package"
      exit
    fi

    # Go, create it    
    ask "" "the file with the MD5 keys of the tarballs has\n  not been created, press ENTER to do it now."
    read x
    > "$TEMPFILE"
    for i in $SOURCEFILES $PATCHFILES
    do
      # Paranoia: check file exists again
      if [ ! -f "$PKG_SRCDEPOT/$i" ]; then
        echoc RED "! file $i no more exist under $PKG_SRCDEPOT"
	exit 1
      fi
      # Add MD5 key
      echo "- checksumming $i"
      ( cd $PKG_SRCDEPOT ; md5sum "$i" >> "$TEMPFILE" )
    done
    echoc GREEN "- md5 keys has been successfully created."
    return
  fi

  echo "- checking MD5 checksums"
  ( cd $PKG_SRCDEPOT && md5sum --check $TEMPFILE )
  if [ $? -ne 0 ]; then
    echoc RED "! some files has an invalid checksum"
    exit 1
  fi
  
  # Next Level
  echo "6" >"$PKGSTEP"
  PKGLEVEL=6
}

##### =====================   fn_package_extract       =========================  #####

fn_package_extract() {
  fn_package_banner
  echoc CYAN "(6) extract sources"
  fn_read_info

  # Anything to check ?
  if [ "$SOURCEFILES" = "" ]; then
    echoc GREEN "- there is no sources that needs to be extracted"
    return
  fi

  # EXTRACT    
  mkdir -p $WORKDIR
  for i in $SOURCEFILES ; do
    # Exploding the tarball
    if [ "$PKGMODE" = "create" ]; then
      echoc YELLOW -n "? Press ENTER to explode $i in $WORKDIR"
      read x
    fi
    #
    echo "- untarring $i ..."
    ( cd $WORKDIR && untar $PKG_SRCDEPOT/$i )
    if [ $? -ne 0 ]; then
      echoc RED "! tarball $i has not been successfully untarred"
      exit 1
    fi
  done

  # SOURCEDIR
  #if [ "$PKGMODE" = "create" ]; then
  # ask  "$SOURCEDIR"  "enter the package SOURCEDIR without any path"
  # read XSOURCEDIR
  # if [ "$XSOURCEDIR" != "" ]; then
  #   SOURCEDIR="$XSOURCEDIR"
      # Save changes to SOURCEDIR
  #   fn_write_info 
  # fi    
  #fi

  # Check if SOURCEDIR really exists
  #if [ ! -d $WORKDIR ]; then
  #    echoc RED "! Directory $SOURCEDIR does not exist under $WORKDIR"
  #    exit 1
  #fi

  # Next Level
  echo "7" >"$PKGSTEP"
  PKGLEVEL=7
}

##### =====================   fn_package_patch         =========================  #####

fn_package_patch() {
  fn_package_banner
  echoc CYAN "(7) apply patches"
  fn_read_info

  # External patch
  if [ "$PATCHFILES" != "" ]; then
    for i in $PATCHFILES ; do
      if [ "$PKGMODE" = "create" ]; then
        echoc YELLOW -n "? press ENTER to apply the patch $i"
        read x
      fi
      ( 
        cd $WORKDIR 
        case $i in
	  *gz)  CMD="gunzip -dc" ;;
	  *bz)  CMD="bunzip -dc" ;;
	  *bz2) CMD="bunzip2 -dc" ;;
	  *zip) CMD="unzip -d" ;;
          *Z)   CMD="uncompress -c" ;;
	  *)    CMD="cat" ;;
        esac
	$CMD "$PKG_SRCDEPOT/$i" | patch -p1
      )
      if [ $? -ne 0 ]; then
        echoc RED "! patch $i has not been successfully applied"
        exit 1
      fi
    done
  fi

  # Internal patch
  if [ -d "$PKGPATCH" ]; then
    for i in $PKGPATCH/* ; do
      if [ "$PKGMODE" = "create" ]; then
        echoc YELLOW -n "? press ENTER to apply the patch $i"
        read x
      fi
      ( cd $WORKDIR && patch $i )
      if [ $? -ne 0 ]; then
        echoc RED "! patch $i has not been successfully applied"
        exit 1
      fi
    done
  fi

  # Next Level
  echo "8" >"$PKGSTEP"
  PKGLEVEL=8
}

##### =====================   fn_package_configure     =========================  #####

fn_package_configure() {
  fn_package_banner
  echoc CYAN "(8) configuring source"
  fn_read_info

  # Ask for docs
  if [ "$PKGMODE" = "create" ]; then
    if [ -x "$WORKDIR/configure" ]; then
      ask "" "Did you read README, INSTALL and the output from ./configure --help\n\
  Type 'YES' to continue without reading it"
      read IAGREE
      if [ "$IAGREE" != "YES" ]; then
        for i in `ls $WORKDIR/* | grep "/[A-Z]"` ; do
	  [ ! -f $i ] && continue
          case "`basename $i`" in
            Change[Ll]og*) continue ;;
            COPYING*) continue ;;
            Make*) continue ;;
          esac
          clear
          echoc CYAN $i
          more $i
          echoc GREEN "- press ENTER to display the next file"
          read x
        done
        clear
        echoc CYAN "Configure help"
        $WORKDIR/configure --help | more
        echoc GREEN "- press ENTER to continue ..."
        read x
        clear
      fi
    fi
  fi
  
  # PRE-CONFIG
  askfile        "$PKGCOMPILE/PRE-CONFIG"  "make distclean"
  fn_run_script  "$PKGCOMPILE/PRE-CONFIG"  "$WORKDIR"

  # CONFIGURE
  if [ -x "$WORKDIR/configure" ]; then
    SUGGEST="CFLAGS='-O6 -mcpu=pentium -malign-loops=2 -malign-jumps=2 -malign-functions=2 -D_REENTRANT' LDFLAGS='-s' ./configure --prefix=/usr --cache-file=/dev/null"
  else
    SUGGEST=""
  fi
  askfile        "$PKGCOMPILE/CONFIGURE"  "$SUGGEST"
  fn_run_script  "$PKGCOMPILE/CONFIGURE"  "$WORKDIR"

  # POST-CONFIG
  askfile        "$PKGCOMPILE/POST-CONFIG"  "make clean"
  fn_run_script  "$PKGCOMPILE/POST-CONFIG"  "$WORKDIR"

  # Next Level
  echo "9" >"$PKGSTEP"
  PKGLEVEL=9
}

##### =====================   fn_package_compile         =========================  #####

fn_package_compile() {
  fn_package_banner
  echoc CYAN "(9) compiling source"
  fn_read_info

  # COMPILE
  askfile        "$PKGCOMPILE/COMPILE"  "make"
  fn_run_script  "$PKGCOMPILE/COMPILE"  "$WORKDIR"

  # MAKE TEST
  askfile        "$PKGCOMPILE/MAKETEST"  "make check"
  fn_run_script  "$PKGCOMPILE/MAKETEST"  "$WORKDIR"

  # Next Level
  echo "10" >"$PKGSTEP"
  PKGLEVEL=10
}

##### =====================   fn_package_install       =========================  #####

fn_package_install() {
  fn_package_banner
  echoc CYAN "(10) installing source"
  fn_read_info

  # PRE-INSTALL
  askfile        "$PKGCOMPILE/PRE-INSTALL"  "make uninstall"
  fn_run_script  "$PKGCOMPILE/PRE-INSTALL"  "$WORKDIR"
  
  # MILESTONE
  if [ "$PKGMODE" = "create" ]; then
    if [ ! -f "$MILESTONE" ]; then
      echoc GREEN "> Creating MILESTONE"
      > "$MILESTONE"
    else
      echo "- Milestone is here"
    fi
  fi

  # INSTALL
  askfile        "$PKGCOMPILE/INSTALL"  "make install"
  fn_run_script  "$PKGCOMPILE/INSTALL"  "$WORKDIR"

  # POST-INSTALL
  askfile        "$PKGCOMPILE/POST-INSTALL"  "ldconfig"
  fn_run_script  "$PKGCOMPILE/POST-INSTALL"  "$WORKDIR"
  
  # Next Level
  echo "11" >"$PKGSTEP"
  PKGLEVEL=11
}

##### =====================   fn_package_scan          =========================  #####

fn_package_scan() {
  fn_package_banner
  echoc CYAN "(11) scanning filesystem"
  [ "$PKGMODE" != "create" ] && return
  fn_read_info

  # Milestone
  if [ ! -f "$MILESTONE" ]; then
    echoc RED    "! No MILESTONE was found"
    echoc YELLOW "  You can press ENTER to continue and create a new MILESTONE ..."
    read x
    touch "$MILESTONE"
    echoc YELLOW "  Milestone has been created, please, now you can just switch"
    echoc YELLOW "  to another vcs to install the software to be packaged, after that"
    echoc YELLOW "  you can press ENTER to begin the analisys of changed files ..."
    read x
  fi

  # Hold your horses
  echoc GREEN -n "> syncing disks ..."
  sync ; sleep 2
  echo " done."
  if [ ! -f "$PKGCOMPILE/INSTALL" ]; then
    echoc GREEN -n "? press ENTER to begin the filesystem scanning"
    read x
  fi
   
  # Scanning ...
  echo "- finding changes into the filesystem ... "
  echo "# Package Create - scanning on `date` " >$CHANGETEMP
  echo "# Please, edit this file removing comment and unwanted entries " >>$CHANGETEMP
  echoc GREEN -n "> Scanning : "
  echo -n " boot "  ; find /boot -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " var "   ; find /var  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " bin "   ; find /bin  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " etc "   ; find /etc  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " lib "   ; find /lib  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " root "  ; find /root -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " sbin "  ; find /sbin -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " usr "   ; find /usr  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo -n " opt "   ; find /opt  -xdev -cnewer $MILESTONE -newer $MILESTONE >>$CHANGETEMP
  echo " sorting "
  cat $CHANGETEMP | grep -v "^$PKGROOT" | sort > $CHANGELIST
  rm -f $CHANGETEMP
  echoc GREEN -n "? press ENTER to edit the file with the list of changes"
  edit $CHANGELIST
  echo "- $CHANGELIST done"
  # TODO: This is a test ... removing milestone at the end of each scan
  rm -f $MILESTONE
  
  # Next Level
  echo "12" >"$PKGSTEP"
  PKGLEVEL=12
}

##### =====================   fn_package_pack          =========================  #####

fn_package_pack() {
  fn_package_banner
  echoc CYAN "(12) packing files from filesystem"
  fn_read_info
  # Check changelist  
  if grep -q "^#" $CHANGELIST ; then
    echoc RED "! please remove comments from $CHANGELIST, then try again"
    exit 1
  fi
  # Pack
  mkdir -p $PKGDIR
  ( cd / ; tar -O -p -T $CHANGELIST -c | tar -v -x -p -C $PKGDIR )
  if [ $? -ne 0 ]; then
    echoc RED "! error while gathering files from the filesystem"
    exit 1
  fi
  echo "> done." 
  # Next Level
  echo "13" >"$PKGSTEP"
  PKGLEVEL=13
}

##### =====================   fn_package_check         =========================  #####

fn_package_check() {
  fn_package_banner
  echoc CYAN "(13) check package's files"
  [ "$PKGMODE" != "create" ] && return
  fn_read_info
  
  # Squeeze
  echo - "> Squeezing $PKGDIR ..."
  find  $PKGDIR \( -name \*~ -or -name \*\# \) -exec rm -vf {} \;

  # Deprecated dirs
  if [ -d $PKGDIR/usr/doc ]; then
    echoc YELLOW "- moveing /usr/doc to /usr/share/doc"
    mv -v $PKGDIR/usr/doc/ $PKGDIR/usr/share/doc/
  fi
  if [ -d $PKGDIR/usr/man ]; then
    echoc YELLOW "- moveing /usr/man to /usr/share/man"
    mv -v $PKGDIR/usr/man/ $PKGDIR/usr/share/man/
  fi
  if [ -d $PKGDIR/usr/info ]; then
    echoc YELLOW "- moveing /usr/info to /usr/share/info"
    mv -v $PKGDIR/usr/info/ $PKGDIR/usr/share/info/
  fi

  # Check obsolete files  
  for i in PRE-DELETE DELETE POST-DELETE PRUNE CONFIGURE doinst.sh \
           PRE-INSTALL INSTALL POST-INSTALL X-POST-INSTALL PRE-REMOVE REMOVE \
           POST-REMOVE CLEANUP PURGE PRUNE 
  do
    if [ -f $PKGINST/$i ]; then
      echoc YELLOW "! File $PKGINST/$i is obsolete !"
      exit 1
    fi
  done

  # Check install scripts
  for i in PRE-INSTALL  INSTALL  POST-INSTALL X-POST-INSTALL \
	    PRE-REMOVE REMOVE POST-REMOVE CLEANUP
  do
    TEMPSCRIPT="$PKGSCRIPT/$i"
    if [ -f $TEMPSCRIPT ]; then
      echo $i
      chmod 700 $TEMPSCRIPT
      chown root.root $TEMPSCRIPT

      grep -q "^set -e" $TEMPSCRIPT
      if [ $? -ne 0 ]; then
        echoc YELLOW "You are not using 'set -e' into this script"
        echo "Press ENTER to continue"
        read x
      fi

      grep -q "^set -x" $TEMPSCRIPT
      if [ $? -eq 0 ]; then
        echoc YELLOW "You are using 'set -x' into this script"
        echo "Press ENTER to continue"
        read x
      fi
    fi
  done

  # Se c'e' incoming ci deve essere anche CLEANUP
  if [ -d $PKGDIR/incoming ]; then
    if [ ! -f $PKGSCRIPT/CLEANUP ]; then
      echoc YELLOW "! directoy 'incoming' is present, you should write a CLEANUP script !"
      echoc YELLOW "  Press ENTER to continue"
      read x
    fi
  fi

  # Icons
  if [ -d $PKGDIR/usr/bin -o -d $PKGDIR/usr/local/bin ]; then
    if [ ! -d $PKGDIR/usr/share/gnome/apps ]; then
      echoc YELLOW "! There are programs but no icons under /usr/share/gnome/apps"
      echoc YELLOW "  Press ENTER to continue"
      read x
    fi
  fi

  # DOCDIR
  DOCDIR="$PKGDIR/usr/share/doc/"
  if [ -d $DOCDIR ]; then
    echoc GREEN "- Changing mode to docs ..."
    find $DOCDIR -type f -exec chmod 644 {} \;
    rmdir $DOCDIR          2>/dev/null
  fi

  # INFO
  if [ -d "$PKGDIR/usr/share/info" ]; then
    #TODO echoc GREEN "- Adding texinfo to the deps"
    #TODO echo $DEPS_INFO >> $PKG_INSTALL/REQUEST
    echo "- Compressing infoes ..."
    find "$PKGDIR/usr/share/info" -type f -exec gzip -9f {} 2>/dev/null \;
    echo "- Changing mode to infoes ..."
    find "$PKGDIR/usr/share/info" -type f -exec chmod 644 {} \;
    # Scripts
    mkdir -m 700 -p $PKGSCRIPT
    touch $PKGSCRIPT/POST-INSTALL
    touch $PKGSCRIPT/PRE-REMOVE
    grep -q "install-info" $PKGSCRIPT/PRE-REMOVE
    if [ $? -ne 0 ]; then
      echoc YELLOW "You are not handling info files in PRE-REMOVE"
      echo "Press ENTER to continue"
      read x
    fi
    grep -q "install-info" $PKGSCRIPT/POST-INSTALL
    if [ $? -ne 0 ]; then
      echoc YELLOW "You are not handling info files in POST-INSTALL"
      echo "Press ENTER to continue"
      read x
    fi
  fi

  # MAN
  if [ -d "$PKGDIR/usr/share/man" ]; then
    #echoc GREEN "[MAN] Adding man to the deps"
    #echo $DEPS_MAN >> $PKG_INSTALL/REQUEST
    echo "- Compressing manpages ..."
    find $PKGDIR/usr/share/man -type f -exec gzip -v9f {} 2>/dev/null \;
    echo "- Changing mode to manpages ..."
    find $PKGDIR/usr/share/man -type f -exec chmod 644 {} \;
  fi

  # Stripping Binaries
  echoc GREEN -n "Stripping  binaries:"
  for i in  "bin"  "sbin"  "usr/bin"  "usr/X11R6/bin"  "usr/sbin"  "usr/local/bin"  "usr/local/sbin" \
		"opt/bin" "opt/sbin"
  do
    if [ -d $PKGDIR/$i ]; then
      echo -n " $i"
      find "$PKGDIR/$i"  -type f -exec strip --strip-unneeded {} 2>/dev/null \;
    fi
    if [ -d $PKGDIR/incoming/$i ]; then
      echo -n "incoming/$i"
      find "$PKGDIR/incoming/$i" -type f -exec strip --strip-unneeded {} 2>/dev/null \;
    fi
  done
  echo "  done."

  # Stripping Libraries
  echoc GREEN -n "Stripping libraries:"
  for i in  "lib"  "sbin"  "usr/lib"  "usr/X11R6/lib"  "usr/local/lib" "opt/lib" ; do
    if [ -d $PKGDIR/$i ]; then
      echo -n " $i"
      find "$PKGDIR/$i" -type f -iname "lib*so*"  -not -name "*.a" -exec strip --strip-unneeded {} \;
    fi
    if [ -d $PKGDIR/incoming/$i ]; then
      echo "incoming/$i"
      find "$PKGDIR/incoming/$i"  -type f  -iname "lib*so*"  -not -name "*.a" -exec strip --strip-unneeded {} \;
    fi
  done
  echo "  done."

  # Next Level
  echo "14" >"$PKGSTEP"
  PKGLEVEL=14
}

##### =====================   fn_package_request       =========================  #####

fn_package_request() {
  fn_package_banner
  echoc CYAN "(14) specify dependencies"
  fn_read_info

  # REQUEST
  ask "$REQUEST" "complete the REQUEST line"
  read XREQUEST
  if [ "$XREQUEST" != "" ] ; then
    REQUEST="$XREQUEST"
    # Save changes
    fn_write_info
  fi

  # Next Level
  echo "15" >"$PKGSTEP"
  PKGLEVEL=15
}

##### =====================   fn_package_build       =========================  #####

fn_package_build() {
  fn_package_banner
  echoc CYAN "(15) building BPP packages"
  fn_read_info

  # Checking BPP structure
  echo "- Checking package structure"
  if [ ! -d $PKGDIR ]; then
      echoc RED "! The package main directory was not found"
      exit 1
  fi
  # Copy Install from the port
  echo "> Copying port directory"
  rm -fR "$PKGDIR/install"
  cp -a "$PKGINST" "$PKGDIR"
  # Check
  if [ ! -d $PKGINST ]; then
      echoc RED "! The package install directory was not found"
      exit 1
  fi
  # Checking files
  for f in  DESCRIPTION  INFO  ; do
    if [ ! -f $PKGINST/$f ]; then
	echoc RED "! Required file $f not found under $PKGINST"
      exit 1
    fi
  done    

  # Checking INFO
  echo "- Checking package infoes"
  if [ "$SONAME" = "" ]; then
    echoc RED "! SONAME is empty"
    exit 1
  fi
  if [ "$VERSION" = "" ]; then
    echoc RED "! VERSION is empty"
    exit 1
  fi

  echo "- Cleaning up ..."
  ( cd $PKGDIR ; rm -f *.tar *.gz *.tgz *.bpp install/MANIFEST* install/AUTOBUILD *.lsm $FULLVERSION )
  find  $PKGDIR \( -name \*~ -or -name \*\# \) -exec rm -vf {} \;

  echo "- preparing BUILDINFO"
  OSNAME="`uname -s`"
  OSVERSION="`uname -r`"
  DISTRIBUTION="$DISTRELEASE"
  BUILDHOST="`hostname`.`domainname`"
  BUILDTIME="`date`"
  BPPVERSION="$PKG_VERSION"

  echo -n "- Preparing DISKUSAGES"
  DISKUSAGES=""
  >$USAGETEMP
  for i in $PKGDIR/* ; do
    [ ! -d $i ] && continue
    BASEDIR="`basename $i`"
    case $BASEDIR in
      usr) continue;;
      install) continue;;
      incoming) continue;;
    esac
    ( cd $PKGDIR ; du -s -b $BASEDIR ) >>$USAGETEMP
  done
  #( cd $PKGDIR ; du -s -b * ; echo ) | grep -v install | grep -v incoming | grep -v usr | grep -v "^$" >$USAGETEMP
  if [ -d $PKGDIR/usr ]; then
    ( cd $PKGDIR ; du usr/* -s -b ; echo ) >>$USAGETEMP
  fi
  DISKUSAGES=`cat $USAGETEMP | while read A B ; do
                echo -n "$A:$B "
              done`
  echo "  ($DISKUSAGES)"
  DISKUSAGE=`du $PKGDIR -s -b | cut -d / -f 1`
  echoc GREEN "- Disk usage of this package is $DISKUSAGE bytes"

  # No more wars to be set then we can save the changes
  BUILDNUMBER=$(( BUILDNUMBER + 1 ))
  fn_write_info

  echo "- Calculating MD5 Checksums ..."
  >$PKGINST/MD5MANIFEST
  ( cd $PKGDIR ; find . -type f -perm +111 | grep -v "^./install/" 1>$PKGINST/MD5TEMP ) 
  ( cat $PKGINST/MD5TEMP ; echo ) | while read f
  do
    [ "$f" = "" ] && continue
    ( cd $PKGDIR ; md5sum "$f" >>$PKGINST/MD5MANIFEST )
  done
  rm -f $PKGINST/MD5TEMP
  cat $PKGINST/MD5MANIFEST
  gzip -9f $PKGINST/MD5MANIFEST

  # Preparing new manifest
  echoc GREEN "- Preparing new MANIFEST"
  ( 
    cd $PKGDIR
    > install/MANIFEST
    [ -d install  ] && find install | grep -v "^$" | grep -v "^install/\..*"  >> install/MANIFEST
    find | cut -b 3- | grep -v "^$" | grep -v "^install" | sort  >> install/MANIFEST
    wc -l install/MANIFEST
  )
  
  # Preparing TAR archive
  echoc GREEN "- Tarring ..."
  #( cd $PKGDIR ; tar  --sparse  --exclude install/.*  --verify  -p  -f $FULLVERSION  -c * )
  ( cd $PKGDIR ; tar  --exclude "install/.*"  --verify  -p -f $FULLVERSION -c * )
  if [ $? -ne 0 ] ; then 
    echo " * * *  T A R - E R R O R  * * *"
    exit 1
  fi

  # Compressing Package
  echo "- Gzipping ..."
  ( cd $PKGDIR ; gzip -v9 -S .bpp $FULLVERSION )
  if [ $? -ne 0 ] ; then
    echo " * * *  G Z I P - E R R O R  * * *"
    exit 1
  fi
  mv ${FULLVERSION}.bpp $PKGROOT
  
  #
  echoc GREEN "Package $FULLVERSION has been successfully builded." 

  # Next Level
  echo "16" >"$PKGSTEP"
  PKGLEVEL=16
}

##### =====================   M  A  I  N   =========================  #####

# Constants
DIST_VERSION="/etc/badpenguin/release"
PACKAGE_CONF="/etc/badpenguin/bpp/package.conf"

# TODO: check $0 for script name
PKGMODE="create"
#PKGMODE="rebuild"
#PKGMODE="repack"
#PKGMODE="build"

# Check Parameters
[ "$1" = "" ] && fn_package_help

# Define package subdirs
fn_read_settings
export PKGROOT="$PKG_PORTSDIR/$1"
export PKGINST="$PKGROOT/install"
PKGINFO="$PKGINST/INFO"
PKGPATCH="$PKGINST/patches"
export PKGCOMPILE="$PKGINST/compile"
PKGSCRIPT="$PKGINST/scripts"
if [ ! -d $PKGROOT ]; then
  echoc YELLOW "! Directory $PKGROOT does not exists,"
  echoc YELLOW "  press ENTER to create it"
  read x
  mkdir -p $PKGROOT
fi

# Resume latest step
PKGSTEP="$PKGROOT/.laststep"
PKGLEVEL=1
if [ "$2" = "" ]; then
  if [ -f $PKGSTEP ]; then
    PKGLEVEL="`cat $PKGSTEP`"
  fi
else
  # Convert $2 into a PKGLEVEL
  case $2 in
    info)			PKGLEVEL=1 ;;
    sourcerequest)	PKGLEVEL=2 ;;
    sourceinfo)		PKGLEVEL=3 ;;
    fetch)			PKGLEVEL=4 ;;
    checksum)		PKGLEVEL=5 ;;
    extract)		PKGLEVEL=6 ;;
    patch)			PKGLEVEL=7 ;;
    configure)		PKGLEVEL=8 ;;
    compile)			PKGLEVEL=9 ;;
    install)		PKGLEVEL=10 ;;
    scan)			PKGLEVEL=11 ;;
    pack)			PKGLEVEL=12 ;;
    check)			PKGLEVEL=13 ;;
    request)		PKGLEVEL=14 ;;
    build)		PKGLEVEL=15 ;;
    announce)		PKGLEVEL=16 ;;
    *) 			PKGLEVEL=0 ;;
  esac
fi

# Init Vars
SHOW_BANNER=0
MILESTONE="$PKGROOT/.milestone"
CHANGELIST="$PKGROOT/.changelist"
CHANGETEMP="$PKGROOT/.changetemp"
USAGETEMP="$PKGROOT/.usagetemp"
WORKDIR="$PKGROOT/.workdir"
PKGDIR="$PKGROOT/.pkgdir"

# Globals
fn_read_settings

# some PKGMODEs ovveride PKGLEVEL
case $PKGMODE in
  repack)
    fn_package_pack
    fn_package_package
    exit 0
    ;;
  build)
    fn_package_package
    exit 0
    ;;
esac

# Go thru' the various steps
[ $PKGLEVEL -le  0 ] && fn_package_help
[ $PKGLEVEL -le  1 ] && fn_package_info
[ $PKGLEVEL -le  2 ] && fn_package_sourcerequest
[ $PKGLEVEL -le  3 ] && fn_package_sourceinfo
[ $PKGLEVEL -le  4 ] && fn_package_fetch
[ $PKGLEVEL -le  5 ] && fn_package_checksum
[ $PKGLEVEL -le  6 ] && fn_package_extract
[ $PKGLEVEL -le  7 ] && fn_package_patch
[ $PKGLEVEL -le  8 ] && fn_package_configure
[ $PKGLEVEL -le  9 ] && fn_package_compile
[ $PKGLEVEL -le 10 ] && fn_package_install
[ $PKGLEVEL -le 11 ] && fn_package_scan
[ $PKGLEVEL -le 12 ] && fn_package_pack
[ $PKGLEVEL -le 13 ] && fn_package_check
[ $PKGLEVEL -le 14 ] && fn_package_request
[ $PKGLEVEL -le 15 ] && fn_package_build
#[ $PKGLEVEL -le 16 ] && fn_package_announce

echo "$0: done at level $PKGLEVEL."
exit 0
