#!/bin/sh
# mkkpkg: make new configured kernel package from kernel-<>-<>.src.rpm
#                                  Time-stamp: "2000-02-29 21:18:10 vine"
#
# [Version 2.3.0] Apr 20 2000
# Modified by SAGAMI <sagami@pc.highway.ne.jp>
# - renewed srpm checking process
# - renewed RPMDIR checking precess
# - and more...
#
# [Version 2.2.5] Mar 3 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - bug fix: set ARCH as i386 (i586 does not make pcmcia now)
# 
# [Version 2.2.4] Feb 29 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - fix a small bug: patch from Shoji Matsumoto
# 
# [Version 2.2.3] Feb 29 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - mkkpkg-2.2.3
# - fix a bug and typo by Lisa Sagami, thanks.
#
# [Version 2.2.2] Feb 25 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - fix a bug: wrong path for SRPMS
# 
# [Version 2.2.1] Feb 25 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - fix a bug: lost definition of RPMRC
# 
# [Version 2.2] Feb 24 2000
# Modified by SAGAMI <sagami@pc.highway.ne.jp>
# - fixed some bugs
#	- 2.1 exits -1 in anyways :-p
#	- BUILDMODE -> RPMBUILDMODE
#	- Some ENV value needs {,}?
#	- RPMDIR sometimes NULL
# - moved /usr/bin/mkkpkg to /usr/sbin/mkkpkg
# - tweaken, using --showrc --rmspec
# - dont include packager tag in new spec file, because rpm will include it
#   if defined in rpmmacros
# - awk ARGV problems in parser
#
# [Version 2.1] Jan 30 2000
# Modified by Jun Nishii <jun@vinelinux.org>
# - merge patch from SAGAMI <sagami@pc.highway.ne.jp>
#      + bug fix for processing .rpmmacros
#      + use --target
#      + added Packager, Vendor, Distribution in new spec file
#      + --clean, --rmsource
#      + use new revision number for new spec file name
#      + modify messages
# - clean up script
#
# [Version 2.0]
# Modified by Jun Nishii <jun@vinelinux.org> Jan 10 2000
# - use parsespec to remove smp, BOOT, BOOTsmp entry
#
# Modified by Yasuhide OOMORI <dasen@typhoon.co.jp>
# - Quick hack about rpmdir.
# - Modified for mistyping of new revision:
#     -- remove control character
# - Modified to quickly make one kernel:
#     -- no compile for smp or BOOT kernel.
#
# [Verion 1.0]
# Written by MATSUMOTO Shoji <vine@flatout.org>
# This script must be distributed by Project Vine <vine@vinelinux.org>.
# The responsibility of any trouble with this script is on you.
#
############################################################

CMDNAME=`basename $0`
TMPFILE="/tmp/$CMDNAME-$$"
DISTRIBUTION=Local
RETVAL=0

############################################################
### get Architecture

MARCH=`uname -m`
case "$MARCH" in
	*86)	ARCH=i386;;
	  *)	ARCH=$MARCH;;
esac

############################################################
### some functions

showUsage(){
	echo "$CMDNAME: make new configured kernel package from kernel-<>-<>.src.rpm"
	echo "usage: $CMDNAME [-v] <sourcepackage> [config|menuconfig|xconfig]"
	return 0
}

checkDir(){
if [ ! -d $1 ] ; then
	echo "directory not found: $1"
	return -1
elif [ ! -w $1 ] ; then
	echo "permission denied: $1"
	return -1
fi
return 0
}

checkFile(){
if [ ! -f $1 ] ; then
	echo "file not found: $1"
	return -1
fi
return 0
}

rpm3var () {
	var=`rpm --showrc \
	 | awk "/-[0-9]+[:=][[:blank:]]+$1[[:blank:]]/ {print \\$3}"`
	while test -n "`echo $var | egrep '%{[_a-zA-Z]+}'`"; do
		v=`echo $var | sed 's/.*%{\([_a-zA-Z]\+\)}.*/\1/'`
		w="`rpm3var $v`"
		var=`echo $var | sed "s,%{\\([_a-zA-Z]\\+\\)},$w,g"`
	done
	echo $var
}

getrpmmacro () {
	macro=`rpm --showrc | grep ^.*[0-9][:=][[:space:]]"$1" \
	 | sed "s/^.*$1[[:space:]]//"`
	echo $macro
}	

############################################################
### process arguments

if [ "$1" = "" ] ; then
	showUsage && exit -1
elif [ "$1" = "-v" ] ; then
	MESG=echo
	shift
else
	MESG=true
fi

SRPM=$1
CONFMETHOD=$2

checkFile $SRPM 
RETVAL=$?
if [ $RETVAL -ne 0 ] ; then
	showUsage && exit -1
fi

case $CONFMETHOD in
	oldconfig)	;;
	config)	;;
	xconfig|Xconfig)	CONFMETHOD=xconfig ;;
	*)	CONFMETHOD=menuconfig ;;
esac	

# Print first banner. Can you read? 
# 34 blue 32 green 35 purple 31 red 33 yellow
$MESG -e "\\033[1;34m$CMDNAME\\033[0;39m verbose mode"
$MESG "$CMDNAME will execute \"make $CONFMETHOD\""

############################################################
## check SRPM and get KVER KREV from it

# checking its signiture...
rpm -K --nopgp $SRPM > /dev/null 
RETVAL=$?
if [ $RETVAL -ne 0 ] ; then
	echo "`basename $SRPM`: didn't pass \"rpm -K\""
	exit -1
fi

# checking if it's srpm...
if [ "`file -L $SRPM | cut -d" " -f4`" != "src" ] ;then
	echo "`basename $SRPM`: does not appear to be src rpm"
	exit -1
fi

# checking if it's kernel...
NAME=`rpm -qp $SRPM --queryformat "%{NAME}"`
if [ "$NAME" != "kernel" ] ; then
	echo "`basename $SRPM`: does not appear to be kernel package"
	exit -1
fi

KVER=`rpm -qp $SRPM --queryformat "%{VERSION}"`
KREV=`rpm -qp $SRPM --queryformat "%{RELEASE}"`
SRPMNAME=${NAME}-${KVER}-${KREV}
#SRPMNAME=`file -L $SRPM | cut -d" " -f6`

############################################################
## set and check RPMDIR

PACKAGER=`getrpmmacro packager`
if [ -z "$PACKAGER" ] ; then
	PACKAGER="$(whoami) <$(whoami)@$(hostname)>"
fi

TOPDIR=`rpm3var _topdir`
BUILDDIR=`rpm3var _builddir`
RPMDIR=`rpm3var _rpmdir`
SPECDIR=`rpm3var _specdir`
SRCDIR=`rpm3var _sourcedir`
SRPMDIR=`rpm3var _srcrpmdir`

for dir in $TOPDIR $BUILDDIR $RPMDIR $SPECDIR \
	$SRCDIR $SRPMDIR $RPMDIR/${ARCH}; do
	checkDir $dir || exit -1
done
#checkDir $RPMDIR/noarch || exit -1
$MESG Using rpmdir: $TOPDIR

############################################################
## extract file names from SRPM

# first $TMPFILE is made here
rpm -qlp $SRPM > $TMPFILE
#SPEC="$TOPDIR/SPECS/`grep '.spec$' $TMPFILE`"
SPEC="$SPECDIR/`grep '.spec$' $TMPFILE`"
KCFG="`grep \"$ARCH.config\" $TMPFILE | tail -1`"

# this is unusual, almost impossible
if [ -z "$SPEC" ] ; then
	echo "can't find spec file"
	rm -f $TMPFILE && exit -1
fi

# as for now, srpm must have "$ARCH.config"
if [ -z "$KCFG" ] ; then
	echo "can't find default configuration file for $ARCH"
	rm -f $TMPFILE && exit -1
fi

$MESG Using specfile: $SPEC
$MESG Using kernel config file: $KCFG

############################################################
## install SRPM: "rpm -i" by root is thought to be a hole...

$MESG "Executing \"rpm -ivh $SRPM\""
rpm -ivh $SRPM >& /dev/null
sync && sleep 1

# cheking files in source dir not only for nosrc, but also for src
$MESG "Checking files in SOURCES..."
for file in `cat $TMPFILE | grep -v '\.spec$'` ; do
	checkFile $SRCDIR/$file
	RETVAL=$?
	if [ $RETVAL -ne 0 ] ; then
		echo "It must be placed in or symbolic linked from ${SRCDIR}"
		rm -f $TMPFILE && exit -1
	fi
done

# first $TMPFILE is removed here
rm -f $TMPFILE

############################################################
## before expand SRPM: it costs a while and overrides BUILD
## check if exists kernel-rebuild.{log,err}
## perhaps someone else is running mkkpkg, really?

for i in kernel-rebuild.log kernel-rebuild.err ; do
	if [ -f /tmp/$i ] ; then
	echo "$CMDNAME found: /tmp/$i"									
	ls -l /tmp/$i
 	echo ""
 	echo "The log might be that of previous attempt, but we don't override it"
 	echo "even if you are root or owner. Delete it and try again. Also check if"
 	echo "someone else(including you) is running $CMDNAME. Thank you."
	exit -1
	fi
done

############################################################
## expand SRPM

$MESG "Executing \"rpm -bp $SPEC\""
# print second -for "panpie"- banner
if [ "$MESG" != "echo" ] ; then
	echo -e "Welcome to \\033[1;35m$CMDNAME\\033[0;39m"
	echo "" && sleep 1
fi

echo "Please wait for a while \"make $CONFMETHOD\" to be executed..."

# expand
rpm -bp $SPEC >& /dev/null

sync && sleep 3
checkDir $BUILDDIR/linux || exit -1

############################################################
## get revision number

while [ "$NREV" = "" ] ; do
	echo -n "Input your Kernel Revision [current: $KREV] "
	read NREV

	# remove control character in string
	NREV=`echo $NREV`

	if [ -f ${RPMDIR}/${ARCH}/kernel-${KVER}-${NREV}.${ARCH}.rpm ] ; then
		echo "${RPMDIR}/${ARCH}/kernel-${KVER}-${NREV}.${ARCH}.rpm found."
		echo -n "  Override? [y/n] "
		read yn
		if [ ! "$yn" = "y" -a ! "$yn" = "Y" ] ; then
			NREV=""
		fi
	else
	# Confirmation of kernel revision
		echo -n "  Your kernel Revision is [revision: $NREV]. OK? [y/n] "
		read yn
		if [ ! "$yn" = "y" -a ! "$yn" = "Y" ] ; then
			NREV=""
		fi
	fi
done

############################################################
## make spec file

NSPEC=${SPECDIR}/kernel-${KVER}-${NREV}.spec
if [ "$NSPEC" = "$SPEC" ] ; then
	mv -f $SPEC ${SPEC}.${CMDNAME}
	SPEC=${SPEC}.${CMDNAME}
fi

PARSESPEC=/usr/lib/mkkpkg/parsespec
if [ ! -x $PARSESPEC ] ; then
	echo "can't execute: $PARSESPEC" && exit -1
fi
$PARSESPEC "$NREV" "$SRPMNAME" "$DISTRIBUTION" "$PACKAGER" "$SPEC" > $NSPEC

$MESG "created new spec file: " $NSPEC
$MESG "  from \"Release: $KREV\" to \"Release: $NREV\""
# dont rm -f $SPEC now

############################################################
## run editor

echo "" && sleep 1
echo "To edit $NSPEC, Push \"Ctrl+Z\" to suspend."
echo -n "  (When finished editting, type \"fg\" to continue.)"
read

#echo "" && sleep 1
#echo "Do you want to edit ${NSPEC}?"
#echo -n "  (In most cases you don't need to edit) [y/n] "
#read yn
#
#if [ "$yn" = "y" -o "$yn" = "Y" ] ; then
#	if [ -z "$EDITOR" ] ; then EDITOR=vi ; fi
#	$EDITOR $NSPEC || echo "can't start editor. Continue..."
#
#	rpm -q --specfile $NSPEC > /dev/null
#	RETVAL=$?
#	if [ $RETVAL -ne 0 ] ; then
#		echo "You made a mistake while editing $NSPEC"
#		exit -1
#	fi
#	UREV="`rpm -q --queryformat "%{RELEASE}\n" --specfile $NSPEC | uniq`"
#	if [ "$UREV" != "$NREV" ] ; then
#		echo "Change detected after edit:" 
#		echo "  from \"Release: $NREV\" to \"Release: $UREV\""
#		NREV=$UREV
#	fi
#fi

############################################################
##

echo -n "Do you want to re-expand sources/patches with new SPEC file? [y/n] "
read yn
if [ "$yn" = "y" -o "$yn" = "Y" ] ; then
	echo executing \"rpm -bp $NSPEC\"
	if rpm -bp $NSPEC > /dev/null ; then
		echo Success.
	else
		echo Failed.
		exit -1
	fi
fi

############################################################
## asking whether to build srpm 

echo -n "Do you want to build SRPM (If no, only RPM will be built)? [y/n] "
read yn
if [ ! "$yn" = "n" -a ! "$yn" = "N" ] ; then
	RPMBUILDMODE="-ba"
	$MESG "Ok, SRPM and RPM will be built."
else
	RPMBUILDMODE="-bb"
	$MESG "Ok, only RPM will be built."
fi

############################################################
## now make config

echo "Ready for make \"$CONFMETHOD\""
echo -n "[Push enter to continue] "
read

if [ -f $BUILDDIR/linux/configs/$KCFG ] ; then
	$MESG "copying .config for $ARCH"
	cp -f $BUILDDIR/linux/configs/$KCFG $BUILDDIR/linux/.config
fi

cd $BUILDDIR/linux 
make $CONFMETHOD
RETVAL=$?

# BUILD/linux is to be deleted afterwards(when -bb)
cd $TOPDIR

if [ $RETVAL -ne 0 ] ; then
	echo -n "Something is wrong with \"make $CONFMETHOD\". Continue? [y/n] "
	read yn
	[ ! "$yn" = "y" -a ! "$yn" = "Y" ] && exit -1
fi

checkFile $BUILDDIR/linux/.config || exit -1

## leaving original and user-defined .configs in SOURCES
$MESG "mv $SRCDIR/${KCFG}{,.mkkpkg}"
mv -f $SRCDIR/${KCFG}{,.mkkpkg}
$MESG "cp .config $SRCDIR/${KCFG}"
cp -f $BUILDDIR/linux/.config $SRCDIR/${KCFG}

# it will create these binaries
rpm -q --specfile $NSPEC | sed "s/$/\.$ARCH\.rpm/g" > $TMPFILE

############################################################
## now build rpm package

sleep 1 && clear
# output lines should be less than 24 lines.
echo ""
echo -e "\\033[1;32m$CMDNAME\\033[0;39m"
echo ""
echo "Now we are prepared for executing:"
echo "  rpm $RPMBUILDMODE $NSPEC --target $ARCH"
echo ""
echo "  Log output goes to /tmp/kernel-rebuild.{log,err}."
echo "  You can read them with following sequence:"
echo "    1. Push \"Ctrl+Z\" to suspend the next long process"
echo "    2. Type \"bg\" to continue background"
echo "    3. Use \"less\" to print /tmp/kernel-rebuild.{log,err}"
echo "    3.1 Push \"Shift+F\" to \"Forward forever; like tail -f\""
echo "    3.2 If you want to stop reading, Push \"Ctrl+C\""
echo "    4. Type \"fg\" to get back to $CMDNAME"
echo "    X. If you are using X, you can read log thru another term window"
echo ""
echo "  It takes about 10-240 minutes depending on your configuration and also"
echo -e "  depending on your machine: It's \\033[1;31mnot freezing!\\033[0;39m" 
echo "" 
echo "Ready for Action?"
echo -n "[Push enter to continue] "
read
echo "Started: `date '+%c'`"
echo -n "Building..."

## Build
KSTARTTIME=`date '+%s'`

rpm $RPMBUILDMODE $NSPEC --target $ARCH \
	> /tmp/kernel-rebuild.log 2> /tmp/kernel-rebuild.err

############################################################
## check return value and whether package are made

RETVAL=$?
KENDTIME=`date '+%s'`
BUILDLAPSE=`expr $KENDTIME - $KSTARTTIME`
if [ $RETVAL -ne 0 ] ; then
	echo "" && echo "Errored: `date '+%c'`"
	echo -n "[Push enter] "
	read
	echo "Some errors were occurred with exitcode $RETVAL."
	echo "Please check /tmp/kernel-rebuild.{log,err}."
	rm -f $TMPFILE && exit -1
fi

echo "" && echo "Finished: `date '+%c'`"
$MESG "Lapse: `expr $BUILDLAPSE / 60` min `expr $BUILDLAPSE % 60` sec"
echo -n "[Push enter] "
read

NEWRPM=${RPMDIR}/${ARCH}/kernel-${KVER}-${NREV}.${ARCH}.rpm
if [ -f $NEWRPM ] ; then
	echo "Created:"
	for i in `cat $TMPFILE` ; do
	[ -f $RPMDIR/${ARCH}/$i ] && ls $RPMDIR/${ARCH}/$i
	done
else
	echo "$NEWRPM does not seem to have been created."
	echo "Please check /tmp/kernel-rebuild.{log,err}."
	rm -f $TMPFILE && exit -1
fi

NEWSRPM="${SRPMDIR}/`rpm -qp $NEWRPM --queryformat "%{SOURCERPM}"`"
if [ "$RPMBUILDMODE" = "-ba" ] ; then
	if [ -f $NEWSRPM ] ; then
		# echo "Created:"
		ls $NEWSRPM
		basename $NEWSRPM >> $TMPFILE
	else
		echo "$NEWSRPM does not seem to have been created."
		# dont exit! it is trivial
		# exit -1
	fi
fi

############################################################
## clean up

echo -n "Do you want to clean up BUILD tree and sources? [y/n] "
read yn
if [ "$yn" = "y" -o "$yn" = "Y" ] ; then
	rpm --rmsource --rmspec --clean --force $NSPEC &> /dev/null
	rm -f $SPEC
fi

echo -n "Do you want to remove kernel-rebuild logs in /tmp? [y/n] "
read yn
if [ "$yn" = "y" -o "$yn" = "Y" ] ; then
	rm -f /tmp/kernel-rebuild.{log,err}
fi

############################################################
## terminates

$MESG "$CMDNAME successfully terminates."
rm -f $TMPFILE
exit 0
