#!/bin/sh

# usage: $0 ARCH BRANCH [-noclean] [-norestr] [-plistcheck] [-nodummy] PKGNAME.tgz DIRNAME [DEPENDENCY.tgz ...]

cleanup()
{
  chroot=$1
  noclean=$2
  error=$3
  cleandirs=$4
  pkgname=$5

  #umount ${chroot}/proc
    
  umount -f ${chroot}/a/ports
  umount -f ${chroot}/usr/opt/doc
  umount -f ${chroot}/usr/src
  umount -f ${chroot}/dev

  if [ $noclean = 0 -o $error = 0 ]; then
    rm -rf ${chroot}/tmp/*
    for dir in ${cleandirs}; do
      if ! rm -rf ${chroot}${dir} >/dev/null 2>&1; then
        chflags -R noschg ${chroot}${dir}
        rm -rf ${chroot}${dir} >/dev/null 2>&1
      fi
    done
    chroot ${chroot} /sbin/ldconfig -R
    if [ ${arch} = "i386" ]; then
	chroot ${chroot} /sbin/ldconfig -aout -R
    fi
    rm -rf ${chroot}/var/db/pkg/*
    rm ${chroot}/used/${pkgname}
    rmdir ${chroot}/used
  fi

  echo -n "$pkgname done on $(hostname -s) at "
  date

  exit $error
}

# configurable variables
pb=/var/portbuild

arch=$1
shift

# Default niceness value
nice=0

. ${pb}/${arch}/portbuild.conf
. ${pb}/scripts/buildenv

buildroot=${scratchdir}
error=0

branch=$1
shift

noclean=0
if [ "x$1" = "x-noclean" ]; then
  noclean=1
  shift
fi
norestr=0
if [ "x$1" = "x-norestr" ]; then
  norestr=1
  export NO_RESTRICTED=1
  shift
fi
plistcheck=0
if [ "x$1" = "x-plistcheck" ]; then
  plistcheck=1
  export PLISTCHECK=1
  shift
fi
nodummy=0
if [ "x$1" = "x-nodummy" ]; then
  nodummy=1
  export NODUMMY=1
  shift
fi

args="$*"

buildenv ${pb} ${arch} ${branch}

pkgname=$(basename $1 ${PKGSUFFIX})
dirname=$2
shift 2

export WRKDIRPREFIX=/tmp
export DISTDIR=/tmp/distfiles
export PACKAGES=/tmp/packages

# to catch missing dependencies
#export DEPENDS_TARGET=/usr/bin/true

# don't pass -j, -k etc. to sub-makes
unset MAKEFLAGS
unset PORTSDIR

# wait 1 hour before killing build with no output
export TIMEOUT=7200

# to prevent runaway processes -- 256 meg file size limit, one hour CPU limit
ulimit -f 524288
ulimit -t 3600

# directories to clean
cleandirs="/usr/local /usr/X11R6 /compat /var/db/pkg"

# 15 minutes
export FTP_TIMEOUT=900
export HTTP_TIMEOUT=900

export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:.

echo "building $pkgname"

chrootdir=${buildroot}/${branch}/chroot
bakdir=${pb}/${arch}/${branch}/tarballs
bindist=${buildroot}/${branch}/tarballs/bindist.tar
packages=${pb}/${arch}/${branch}/packages

found=0
for dir in ${chrootdir}/*; do
  if [ -d ${dir}/tmp -a ! -e ${dir}/used ]; then
    mkdir ${dir}/used 2>/dev/null
    touch ${dir}/used/${pkgname}
    if [ $(echo $(echo ${dir}/used/* | wc -w)) = 1 ]; then
      found=1
      chroot=${dir}
      break
    else
      rm ${dir}/used/${pkgname}
      rmdir ${dir}/used 2>/dev/null
    fi
  fi
done

if [ ${found} != 1 ]; then
  chroot=${chrootdir}/$$
  while [ -d ${chroot} ]; do
    chroot=${chroot}-
  done

  mkdir -p ${chroot}/used
  touch ${chroot}/used/${pkgname}
  tar -C ${chroot} -xpf ${bindist}

  # to be able to run ps and killall inside chroot area
  cp -p /bin/ps ${chroot}/bin
  cp -p /usr/bin/killall ${chroot}/usr/bin
fi

# Figure out jail IP addr
chrootpid=$(basename ${chroot})
ip1=$(($chrootpid /(256*256)))
ip2=$((($chrootpid - ($ip1*256*256)) /256))
ip3=$((($chrootpid - ($ip1*256*256) - ($ip2*256))))

# Set up desired uname version
echo ${OSREL}-${BRANCH} > ${chroot}/usr/bin/UNAME_VERSION

trap "cleanup ${chroot} ${noclean} ${error} \"${cleandirs}\" ${pkgname}" 1 2 3 9 10 11 15 

rm -rf ${chroot}/tmp/*
cd ${chroot}/tmp
mkdir -p depends distfiles packages

echo "building ${pkgname} on $(hostname -s)" | tee ${chroot}/tmp/${pkgname}.log
echo "in directory ${chroot}" | tee -a ${chroot}/tmp/${pkgname}.log
echo "with arguments: ${args}" | tee -a ${chroot}/tmp/${pkgname}.log

# intentionally set up ${PORTSDIR} with symlink to catch broken ports
mkdir -p ${chroot}/a/ports
rm -rf ${chroot}/usr/ports
mount -o nfsv3,intr -r ${master}:${pb}/${arch}/${branch}/ports ${chroot}/a/ports
ln -sf ../a/ports ${chroot}/usr/ports

mkdir -p ${chroot}/usr/src ${chroot}/usr/opt/doc

mount -o nfsv3,intr -r ${master}:${pb}/${arch}/${branch}/src ${chroot}/usr/src
mount -o nfsv3,intr -r ${master}:${pb}/${arch}/${branch}/doc ${chroot}/usr/opt/doc

mount -t devfs foo ${chroot}/dev

# just in case...
for dir in ${cleandirs}; do
  if ! rm -rf ${chroot}${dir} >/dev/null 2>&1; then
    chflags -R noschg ${chroot}${dir}
    rm -rf ${chroot}${dir} >/dev/null 2>&1
  fi
done

rm -rf ${chroot}/var/db/pkg/*

mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.root.dist -p ${chroot} \
  >/dev/null 2>&1
mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.var.dist -p ${chroot}/var \
  >/dev/null 2>&1
mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.usr.dist -p ${chroot}/usr \
  >/dev/null 2>&1
mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.local.dist -p ${chroot}/usr/local \
  >/dev/null 2>&1

if [ $XFREE86_VERSION = 4 ]; then
  mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.x11-4.dist -p ${chroot}/usr/X11R6 \
    >/dev/null 2>&1
else
  mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.x11.dist -p ${chroot}/usr/X11R6 \
    >/dev/null 2>&1
fi

chroot ${chroot} /sbin/ldconfig -m /usr/lib/compat
chroot ${chroot} /sbin/ldconfig -R
if [ ${arch} = "i386" ]; then
	chroot ${chroot} /sbin/ldconfig -aout -m /usr/lib/aout
	chroot ${chroot} /sbin/ldconfig -aout -m /usr/lib/compat/aout
	chroot ${chroot} /sbin/ldconfig -aout -R
fi

while [ $# -gt 0 ]; do
  if [ -f ${packages}/All/$1 ]; then
    if [ ! -f ${chroot}/tmp/depends/$1 ]; then
      echo "copying package $1 for ${pkgname}"
      cp -p ${packages}/All/$1 ${chroot}/tmp/depends
    fi
  else
    echo "skipping package $1 for ${pkgname} since it is missing"
  fi
  shift
done

cp -p ${pb}/scripts/buildscript ${chroot}
cp -p ${pb}/scripts/pnohang.${arch} ${chroot}/pnohang

# phase 1, make checksum
# Needs to be chroot so that port can be fetched
chroot ${chroot} /buildscript ${dirname} 1 2>&1 | tee -a ${chroot}/tmp/${pkgname}.log
if [ -f ${chroot}/tmp/status ]; then
  error=$(cat ${chroot}/tmp/status)
else
  error=255
fi

if [ "${error}" = 0 ]; then
# make checksum succeeded
  ssh -a -x ${user}@$master mkdir -p ${pb}/${arch}/${branch}/distfiles/.pbtmp/${pkgname}
  tar -C ${chroot}/tmp/distfiles -cf - . | \
    ssh -a -x ${user}@$master tar --unlink -C ${pb}/${arch}/${branch}/distfiles/.pbtmp/${pkgname} -xvf -
  ssh -a -x ${user}@$master touch ${pb}/${arch}/${branch}/distfiles/.pbtmp/${pkgname}/.done

# phase 2, make package
  ln -sf ${pkgname}.log2 ${chroot}/tmp/make.log

  ifconfig lo0 alias 10.${ip1}.${ip2}.${ip3}/32
  jail ${chroot} jail-${chroot} 10.${ip1}.${ip2}.${ip3} /usr/bin/nice -n $nice /buildscript ${dirname} 2 > ${chroot}/tmp/${pkgname}.log2 2>&1
  ifconfig lo0 delete 10.${ip1}.${ip2}.${ip3}

  grep pnohang ${chroot}/tmp/${pkgname}.log2
  cat ${chroot}/tmp/${pkgname}.log2 >> ${chroot}/tmp/${pkgname}.log
  rm ${chroot}/tmp/${pkgname}.log2
###  chroot ${chroot} /buildscript ${dirname} 2 2>&1 | tee -a ${chroot}/tmp/${pkgname}.log
  scp ${chroot}/tmp/${pkgname}.log ${user}@${master}:${pb}/${arch}/${branch}/logs/${pkgname}.log
  error=$(cat ${chroot}/tmp/status)

  if [ -e ${chroot}/tmp/work.tbz ]; then
	scp ${chroot}/tmp/work.tbz ${user}@${master}:${pb}/${arch}/${branch}/wrkdirs/${pkgname}.tbz
  fi

  if [ "${error}" = 0 ]; then
    tar -C ${chroot}/tmp -cf - packages | \
      ssh -a -x ${user}@$master tar --unlink -C ${pb}/${arch}/${branch} -xvf -
    ssh -a -x ${user}@$master [ -f ${pb}/${arch}/${branch}/packages/All/${pkgname}${PKGSUFFIX} ] '&&' touch ${pb}/${arch}/${branch}/packages/All/${pkgname}${PKGSUFFIX}
    ssh ${user}@$master rm -f ${pb}/${arch}/${branch}/errors/${pkgname}.log
    ssh ${user}@$master lockf ${pb}/${arch}/${branch}/failure.lock ${pb}/scripts/buildsuccess ${arch} ${branch} ${pkgname}
  else
    scp ${chroot}/tmp/${pkgname}.log ${user}@${master}:${pb}/${arch}/${branch}/errors/${pkgname}.log
    ssh ${user}@$master lockf ${pb}/${arch}/${branch}/failure.lock ${pb}/scripts/buildfailure ${arch} ${branch} ${pkgname}
  fi

else
  scp ${chroot}/tmp/${pkgname}.log ${user}@${master}:${pb}/${arch}/${branch}/errors/${pkgname}.log
  scp ${chroot}/tmp/${pkgname}.log ${user}@${master}:${pb}/${arch}/${branch}/logs/${pkgname}.log
  ssh ${user}@$master lockf ${pb}/${arch}/${branch}/failure.lock ${pb}/scripts/buildfailure ${arch} ${branch} ${pkgname}
fi

cleanup ${chroot} ${noclean} ${error} "${cleandirs}" ${pkgname}
