#!/bin/sh

. ./scripts/parse-config

if [ "$arch" = any ] ; then
	echo
	echo "ERROR: No architecture configured."
	echo
	echo "Type './scripts/Help Config' for details."
	echo
	exit 1
fi

buildstart="`date "+%m/%d/%Y from %T"`"

clear_src=1
make_tar=0
norebuild=0
options=''

export SHELL="/bin/bash"

#
# ----  Functions
#

# This function is used for focing a file to be in the flist
#
add_flist() {
	for addfile ; do
		touch "$addfile"
		mv "$addfile" "$addfile.$$"
		mv "$addfile.$$" "$addfile"
	done
}

# This function is used by some build scripts for
# installing SysV-Init Scripts
#
install_init() {
	spri=$2 ; kpri=`expr 100 - $spri`
	name=$1 ; initdir="$root/etc/init.d"
	shift ; shift
	#
	echo -n "Install Init script '$name' ($spri/$kpri): "
	cat > $initdir/$name ; chmod +x $initdir/$name
	add_flist $initdir/$name
	#
	while [ ".$1" != "." ]
	do
		echo -n " $1"
		ln -sf ../$name $initdir/$1.d/S$spri$name
		ln -sf ../$name $initdir/$1.d/K$kpri$name
		shift
	done
	#
	echo -n " rcX"
	echo "The script '$name' has the priority $spri." > $initdir/rcX.d/X$spri$name
	add_flist $initdir/rcX.d/X$spri$name
	echo " done."
}

install_gdm() {
	echo "generating GDM Session for: $1 which executes: $2 ..."
	mkdir -p /etc/gdm/Sessions
	cat $base/scripts/gdm.skeleton |
	  sed "s,xxxx,$1,g" | sed "s,yyyy,$2,g" | sed "s,zzzz,$3,g" > /etc/gdm/Sessions/$1
	chmod +x /etc/gdm/Sessions/$1
}

parse_pkg_desc() {
	x="`egrep "^$1\[(S|STATUS)\]" "$2" | head -1 | sed 's,^[^]]*] *,,'`"
	if [ "$x" ] ; then x="`echo $x | tr a-z A-Z`" ; else x=ALPHA ; fi
	echo -n "Status: $x,  License: "

	x="`egrep "^$1\[(L|LICENSE)\]" "$2" | head -1 | sed 's,^[^]]*] *,,'`"
	[ "$x" ] || x="Unknown"
	grep "  $x	" Documentation/Developers/REGISTER | \
		head -1 | sed 's,^  ,,; s,	, (,; s,$,),' | tr -d '\t'
	echo

	x="`egrep "^$1\[(I|TITLE)\]" "$2" | head -1 | sed 's,^[^]]*] *,,'`"
	[ "$x" ] && echo -e "  $x\n"

	egrep "^$1\[(T|TEXT)\]" "$2" | sed 's,^[^]]*] *,  ,'

	x="`egrep "^$1\[(U|URL)\]" "$2" | sed 's,^[^]]*] *,,'`"
	[ "$x" ] && { echo -e "\nURL(s):" ; echo "$x" | sed 's,^,  ,' ; }

	x="`egrep "^$1\[(A|AUTHOR)\]" "$2" | sed 's,^[^]]*] *,,'`"
	[ "$x" ] && { echo -e "\nOriginal Author(s):"
	              echo "$x" | sed 's,^,  ,' ; }

	x="`egrep "^$1\[(M|MAINTAINER)\]" "$2" | sed 's,^[^]]*] *,,'`"
	[ "$x" ] && { echo -e "\nROCK Package Maintainer(s):"
	              echo "$x" | sed 's,^,  ,' ; }
}

pkg_skip() {
	if [ ".$pkg" = ".$1" ] ; then
		echo -n " skip!" ; exit_now=0
		if [ ".$ver" != ".$2" ] ; then
			echo -n " [old_ver]" ; exit_now=1
		fi
	fi
}

help_msg() {
	echo
	echo "Usage: ./scripts/Build-Pkg [ -1 .. -5 ]" \
	     "[ -noclearsrc ] [ -maketar ]  \\"
	echo "                           [ -norebuild ]" \
	     "pkg-name(s)"
	echo
	echo "Type './scripts/Help Build-Pkg' for details."
	echo
}

#
# ---- Parse options and run 'make-env'
#

this_is_the_2nd_run=0

while [ "$1" ] ; do
	case "$1" in
		-this_is_the_2nd_run) this_is_the_2nd_run=1 ;;
		-1) options="$options $1" ; stagelevel=1 ;;
		-2) options="$options $1" ; stagelevel=2 ;;
		-3) options="$options $1" ; stagelevel=3 ;;
		-4) options="$options $1" ; stagelevel=4 ;;
		-5) options="$options $1" ; stagelevel=5 ;;
		-noclearsrc) options="$options $1" ; clear_src=0 ;;
		-maketar)    options="$options $1" ; make_tar=1  ;;
		-norebuild)  options="$options $1" ; norebuild=1 ;;
		-*) help_msg ; exit 1 ;;
		*) break ;;
	esac
	shift 1
done

if [ -z "$1" ] ; then
    help_msg ; exit 1
elif [ "$2" ] ; then
    for x ; do
	if ! ./scripts/Build-Pkg $options $x && \
	   [ $abortonerror = 1 ] ; then
		exit 1
	fi
    done
    exit 0
fi

# slightly hacky - since we do not want to have our interactive mv and co ...
if [ $stagelevel -gt 2 ] ; then
	for x in /etc/profile.d/* ; do
		[ -e $x ] && . $x
	done
fi

. ./scripts/make-env
[ $this_is_the_2nd_run = 1 ] ||
	exec ./scripts/Build-Pkg -this_is_the_2nd_run $options "$1"

#
# ----  Prepare Build
#

pkg=${1#pkg-config/}
pkg=${pkg%.ext}
pkg=${pkg%/}

flistdel="etc/ld.so.cache|usr/share/info/(dir|standards.info)|var/tmp/.*"
flistdel="$flistdel|var/adm/.*\\.out|.*\\.old"

if [ $stagelevel = 1 ]
then
	root="$base/dist"
	baseconfopt="--build=$build --host=$target"
	confopt="$baseconfopt --prefix=$root/usr"
else
	baseconfopt="--build=$target"
	confopt="$baseconfopt --prefix=/usr"
	flistdel="$flistdel|`echo $base | sed s,^/,,`/.*"
fi

# z are the dRock 2nd CD packages
#
logpf=$stagelevel

if [ $norebuild = 1 -a -f $root/var/adm/logs/$logpf-$pkg.log ] ; then
	date "+== %D %T =[$stagelevel]=> Package $pkg already built. Skipping."
	exit 0
fi

if [ $retryfailed = 0 -a $norebuild = 1 -a -f $root/var/adm/logs/$logpf-$pkg.err ] ; then
	date "+== %D %T =[$stagelevel]=> Package $pkg already failed. Skipping."
	exit 1
fi

start_time=`date "+%s"`

mkdir -p $root/var/adm/logs/
rm -f $root/var/adm/logs/$logpf-$pkg.out
rm -f $root/var/adm/logs/$logpf-$pkg.log
rm -f $root/var/adm/logs/$logpf-$pkg.err

if grep '^[xoz]' scripts/packages | cut -d ' ' -f5 | grep -xq "$pkg"
then
	confdir="$base/pkg-config/$pkg"
	archdir="$base/pkg-archive"
	
	ver=`grep '^[xoz]' scripts/packages | cut -d ' ' -f5,6 | grep "^$pkg " | cut -d ' ' -f2`
	if [ ".$ver" = ".0000" ] ; then ver="$rockver" ; fi
	extraver="$rockver"

	date "+== %D %T =[$stagelevel]=> Going to build base package $pkg [$ver $extraver]."

	echo -n 'Pkg-Config:'

	patchfiles="`echo $confdir/*.patch | grep -v '\*' || true`"
	[ "$patchfiles" ] && echo -n " patches"

	stripexpr='(.*/|)(bin|sbin|libexec)/.*'
	pkgdesc="`echo -e '\n  No package description available.'`"
	prepatch="" ; postpatch="" ; preconf="" ; configprefix=""
	premake="" ; inmake="" ; postmake="" ; makeinstopt="install"

	srcdir=none ; srctar=none
	taropt="--use-compress-program=bzip2 -xf"

	runconf=1 ; runxmkmf=1 ; autoextract=1 ; disablekshell=0

	export includedir=$root/usr/include
	export prefix=$root/usr
	export sysconfdir=$root/etc
	export docdir=$root/usr/share/doc/packages/$pkg
	mkdir -p $docdir

	if [ $stagelevel -le 1 ] ; then
		makeopt="prefix=/usr includedir=$includedir CC='$CC' CXX='$CXX'"
	else
		makeopt=" "
	fi

	if [ -f $confdir/$pkg.desc ] ; then
		echo -n " $pkg.desc"
		pkgdesc="`parse_pkg_desc '' $confdir/$pkg.desc`"
	fi

	exit_now=x

	if [ -f $confdir/$pkg.conf ] ; then
		echo -n " $pkg.conf" ; . $confdir/$pkg.conf
	fi
	if [ -f $base/arch-conf/$arch/pkg-header ] ; then
		echo -n " pkg-header" ; . $base/arch-conf/$arch/pkg-header
	fi

	if [ $exit_now = 1 ] ; then
		echo -e "Found error(s) in package config file(s)." \
			>> $root/var/adm/logs/$logpf-$pkg.err
		echo ; cat < $root/var/adm/logs/$logpf-$pkg.err | \
			sed 's,^,> ,; s/^\(.\{70\}\).\{3,\}/\1 ../'
		date "+== %D %T =[$stagelevel]=> Aborted building package $pkg [$ver $extraver]."
		exit 1
	fi
	if [ $exit_now = 0 ] ; then
		echo -e "Disabled in package config file(s)." \
			>> $root/var/adm/logs/$logpf-$pkg.log
		date "+== %D %T =[$stagelevel]=> Finished building package $pkg [$ver $extraver]."
		exit 0
	fi

	echo " done."
else
	date "+== %D %T =[$stagelevel]=> No such package: $pkg !" ; exit 1
fi

umount src/*.mnt src/*/*.mnt 2> /dev/null

if [ $clear_src = 1 ] ; then
	rm -rf src/ ; mkdir -p src
fi

if [ $useflwrapper = 1 ] ; then
	rm -f src/temp.fl_wrapper.out
	touch src/temp.fl_wrapper.out
else
	touch src/temp.time_stamp
	sleep 2
fi

#
# ----  Build Package
#

{
 trap 'exit 1' INT
 exec < /dev/null
 
 set -e

 # Makes debugging build problems easier
 export > $base/src/debug.buildenv
  
 if [ $autoextract = 1 ] ; then

 # Autodedect source tar and extract it
 #
 if [ $srctar = none ] ; then
	cd $archdir
	for x in $pkg[-_.]$ver.tar.bz2 $pkg$ver.tar.bz2 $pkg.tar.bz2 \
	         $pkg[-_.]$ver.tbz2 $pkg$ver.tbz2 $pkg.tbz2 ; do
		if [ -f "$x" ] ; then srctar=$x ; break ; fi
	done
	if [ $srctar = none ] ; then
		echo "Can't auto-dedect srctar for package '$pkg'!" ; exit 1
	fi
 fi
 #
 ls -l $archdir/$srctar
 echo -n "Extracting $srctar ($taropt) ... " ; cd $base/src
 tar $taropt $archdir/$srctar ; echo done.

 # Autodedect source dir and change to it
 #
 if [ $srcdir = none ] ; then
	for x in $pkg[-_.]$ver $pkg$ver $pkg $pkg* ; do
		if [ -d "$x" ] ; then srcdir=$x ; break ; fi
	done
	if [ $srcdir = none ] ; then
		echo "Can't auto-dedect srcdir for package '$pkg'!" ; exit 1
	fi
 fi
 #
 cd $base/src/$srcdir

 # Apply patches
 #		
 [ ".$prepatch" = "." ] || eval $prepatch
 #
 for x in $patchfiles ; do
	echo "Apply patch $x ..."
	patch -bfp1 -z .orig < $x
 done
 #
 [ ".$postpatch" = "." ] || eval $postpatch

 else
	cd $base/src
 fi

 CRUX="$CC_WRAPPER_SILENT"
 export CC_WRAPPER_SILENT="0"
 echo "gcc wrapper test: "
 gcc -v
 export CC_WRAPPER_SILENT="$CRUX"
 unset CRUX

 if [ ".$custmain" = "." ] ; then
	# Run configure scripts etc.
	#
	[ ".$preconf" = "." ] || eval $preconf

	if [ $disablekshell = 1 ]; then
		sed "s,/bin/ksh,/bin/bash," < configure > configure_new
		mv configure_new configure
		chmod 755 configure
	fi

	#	
	if [ $runconf = 1 -a -f ./configure ]
	then
		if [ $stagelevel = 1 ] ; then
			{ cat $base/scripts/config.cache
			echo -e "\n# Architecture specific stuff\n"
			echo "ac_cv_sizeof_short=$arch_sizeof_short"
			echo "ac_cv_sizeof_int=$arch_sizeof_int"
			echo "ac_cv_sizeof_long=$arch_sizeof_long"
			echo "ac_cv_sizeof_long_long=$arch_sizeof_long_long"
			echo "ac_cv_sizeof_char_p=$arch_sizeof_char_p"
			echo "ac_cv_c_bigendian=$arch_bigendian" ; } > config.cache
		fi
		echo "running \"./configure $confopt\""
		eval "$configprefix ./configure $confopt"
	fi
	#
	if [ ! -f Makefile -a ! -f makefile -a \
	     -f Imakefile -a $runxmkmf = 1 ] ; then
		xmkmf -a
	fi

	# Build it
	#		
	[ ".$premake"     = "." ] || eval "$premake"
	[ ".$makeopt"     = "." ] || eval "$MAKE $makeopt"
	[ ".$inmake"      = "." ] || eval "$inmake"
	[ ".$makeinstopt" = "." ] || eval "$MAKE $makeinstopt"
	[ ".$postmake"    = "." ] || eval "$postmake"

 else
	eval "$custmain"
 fi
 
 echo "Copying additional package documentation ..."
 if [ $autoextract  = 1 ]; then
   # make shure we are in the right dir
   cd $base/src/$srcdir 

   for docfile in [A-Z][A-Z]* *.lsm ChangeLog ; do
   	if [ -f $docfile ]; then
	  cp -v $docfile $docdir
	else
	  echo "DEBUG: tried to copy non existing doc file ..."
	fi
   done
 fi

 echo "Copying additional ROCK config examples ..."
 for x in $confdir/*.cfg_exp ; do
	if [ -f $x ]; then 
	  mkdir -p $docdir/config-example
	  dest=`basename $x | sed "s,.cfg_exp,,"` 
	  cp -vf $x $docdir/config-example/$dest
	else
	  echo "DEBUG: tried to copy non existing cfg_exp file ..."
	fi 
 done 

 cd $root/

 echo "Making some other adaption ..."
 #
 find usr/share/man -type f -name '*.gz' | xargs -r gunzip -fv
 chmod -R u=rwX,g=rX,o=rX $root/usr/share/man
 chown -R root. $root/usr/share/man

 #
 [ $stagelevel -gt 2 -a -f /sbin/ldconfig ] && /sbin/ldconfig -q

 echo -n "Creating file list ... "
 #
 rm -f $base/src/temp.lst
 for x in var/adm/flists/$pkg var/adm/md5sums/$pkg \
          var/adm/cksums/$pkg var/adm/packages/$pkg ; do
 	touch $x ; echo "$x" >> $base/src/temp.lst
 done
 if [ "$pkg" = "00-dirtree" ] ; then
 	if find * \( -not -type d -or -type d -empty \) \
 		-printf "%p\n" | grep -v "^var/adm/" >> $base/src/temp.lst
 	then : ; fi
 elif [ $useflwrapper = 1 ] ; then
 	mv $base/src/temp.fl_wrapper.out $base/src/temp.out
	
	x="`echo $pkg | sed 's,+,\\\\+,g'`"
 	if $base/lib/fl_wrparse < $base/src/temp.out | \
 		grep "^$root/" | sed "s,^$root/,," | \
 		egrep "^(bin|boot|etc|lib|sbin|usr|var|opt)/" \
 		>> $base/src/temp.lst
 	then : ; fi
	
 	rm -f $base/src/temp.out
 else
 	if find bin boot etc lib sbin usr var opt \
 		\( -not -type d -or -type d -empty \) \
 		-and \( -newer $base/src/temp.time_stamp -or \
 		-cnewer $base/src/temp.time_stamp \) -printf "%p\n" \
 		>> $base/src/temp.lst
 	then : ; fi
 fi
 
 # mix-in a last stage's flist file - maybe a package has not overwritten
 # an allready existing file ?
 if [ -f var/adm/flists/$pkg ] ; then
 	cut -f2 -d' ' var/adm/flists/$pkg >> $base/src/temp.lst
 fi
 
 # finally sort and remove flistdel entries ...
 # (Rene: was this bug hard to find!)
 sort -u $base/src/temp.lst | egrep -v "^($flistdel)\$" | \
	sort | uniq | \
	sed "s,^,$pkg: ," \
 	> var/adm/flists/$pkg
 
 echo "`wc -l < var/adm/flists/$pkg` files."
 rm -f $base/src/temp.lst

 echo "Clear md5sums and cksums ..."
 cat /dev/null > var/adm/md5sums/$pkg
 cat /dev/null > var/adm/cksums/$pkg

# if [ ".$stripbins" != .0 ] ; then
# 	echo "Trying to strip as much as possible ... "
# 	cat var/adm/flists/$pkg | egrep " $stripexpr\$" | \
# 	$base/lib/getfiles | xargs $STRIP -s -v 2> /dev/null || true
# fi

 echo "Creating package description ..."
 #
 grep "^Build \[.\] at " var/adm/packages/$pkg > $base/src/temp.bld || true
 { echo "Package Name and Version: $pkg $ver $extraver"
 echo "Package Size: `$base/lib/getdu $root/ < var/adm/flists/$pkg`," \
      "`wc -l < var/adm/flists/$pkg | tr -d ' '` files"
 echo "ROCK Linux Version and Architecture: $rockver $arch"
 echo "Build on `uname -m -n -r -s -p`"
 cat $base/src/temp.bld ; rm $base/src/temp.bld
 echo "Build [$stagelevel] at $buildstart to `date "+%T %Z"`"
 echo -e "$pkgdesc\n\n----"
 { grep " $1 " $base/scripts/packages | expand | \
 	sed 'y/ /%/; s/%\(%*\)%/ \1 /g; s/%\([^% ]\)/ \1/g; y/%/./;'
 }
 } > var/adm/packages/$pkg

 touch $root/var/adm/logs/$logpf-$pkg.log

 set +e

} 2>&1 | {
	trap '' INT

	echo "Building. Writing output to $root/var/adm/logs/$logpf-$pkg.out"

	if [ $dontprintlogs = 1 ] ; then
		cat > $root/var/adm/logs/$logpf-$pkg.out
	else
		tee $root/var/adm/logs/$logpf-$pkg.out
	fi
}

#
# ----  Finish and Cleanup
#

cd $base

if [ $make_tar = 1 ] ; then
	./scripts/Build-Tar $root/ $pkg
fi

umount src/*.mnt src/*/*.mnt 2> /dev/null

end_time=`date "+%s"`
consumed_time=$((end_time - start_time))

if [ -f $root/var/adm/logs/$logpf-$pkg.log ] ; then
	if [ $clear_src = 1 ] ; then rm -rf src/ ; mkdir -p src ; fi
	echo "$root/var/adm/logs/$logpf-$pkg.out -> $logpf-$pkg.log"
	mv $root/var/adm/logs/$logpf-$pkg.out \
		$root/var/adm/logs/$logpf-$pkg.log
	
	echo "Elapsed time: $((consumed_time / 60))m:$((consumed_time % 60))s"
	date "+== %D %T =[$stagelevel]=> Finished building package $pkg [$ver $extraver]."

	exit 0
else
	if [ $dontprintlogs = 1 ] ; then
		echo "`tail -n 20 < $root/var/adm/logs/$logpf-$pkg.out`" | \
			sed 's,^,> ,; s/^\(.\{70\}\).\{3,\}/\1 ../'
	fi
	echo "$root/var/adm/logs/$logpf-$pkg.out -> $logpf-$pkg.err"
	mv $root/var/adm/logs/$logpf-$pkg.out \
		$root/var/adm/logs/$logpf-$pkg.err
	
	echo "Elapsed time: $((consumed_time / 60))m:$((consumed_time % 60))s"
	date "+== %D %T =[$stagelevel]=> Aborted building package $pkg [$ver $extraver]."
	exit 1
fi

# ----  EOF
