#!/bin/bash
################################################################################
# Filename: ./src/base/etc/templates/qrm-create-initrd-template
# 
# The contents of this file are subject to the Qlusters Public License
# Version 1.1 (the License); you may not use this file except in compliance
# with the License.
# You may obtain a copy of the License at
# http://www.openqrm.org/content/view/33/69/.
# 
# Software distributed under the License is distributed on an AS IS basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
# the specific language governing rights and limitations under the License.
# 
# The Original Code is openQRM.
# 
# The Initial Developer of the Original Code is Qlusters Corporation. Portions
# created by Qlusters Corporation are Copyright (C) 2003-2005. All Rights
# Reserved.
# 
# Contributor(s):
# 
# Description:
# 
# Comments:
################################################################################

# script to automatically create an initrd

INITRD_TEMPLATE_DIR=`pushd \`dirname $0\` 1>/dev/null && pwd && popd 1>/dev/null`
INITRD_DIRECTORIES="bin dev dev/iscsi etc etc/rc.d/init.d etc/sysconfig etc/X11 lib lib/modules lib/i686 loopfs mnt old_root proc sys sysroot usr usr/lib usr/bin usr/sbin var var/lock var/lock/subsys var/log var/run"
INITRD_DEVICES_COMMON="console loop0 loop1 loop2 loop3 loop4 loop5 null ram ram1 ram2 ram3 systty tty0 tty1 tty2 tty3 tty4 zero mem stderr stdin stdout"
INITRD_DEVICES_ROOT="/dev/root b 0 255"
INITRD_DEVICES_NFS="/dev/nfs b 0 255"
INITRD_DEVICES_PS2="/dev/psaux c 10 1"
INITRD_BINARIES="bash portmap strace stat"
PACKAGE_CONFIG_FILE_BUSYBOX="$INITRD_TEMPLATE_DIR/conf/busybox.conf"
PACKAGE_CONFIG_FILE_KUDZU="$INITRD_TEMPLATE_DIR/conf/kudzu.conf"
PACKAGE_CONFIG_FILE_HWSETUP="$INITRD_TEMPLATE_DIR/conf/hwsetup.conf"
PACKAGE_CONFIG_FILE_HWDATA="$INITRD_TEMPLATE_DIR/conf/hwdata.conf"
PACKAGE_CONFIG_FILE_DDCXINFO="$INITRD_TEMPLATE_DIR/conf/ddcxinfo.conf"
PACKAGE_CONFIG_FILE_XF86CONFIG="$INITRD_TEMPLATE_DIR/conf/xf86config.conf"
PACKAGE_CONFIG_FILE_E2FSPROGS="$INITRD_TEMPLATE_DIR/conf/e2fsprogs.conf"
PACKAGE_CONFIG_FILE_MODUTILS="$INITRD_TEMPLATE_DIR/conf/modutils.conf"
PACKAGE_PATCH_FILE_MODUTILS="$INITRD_TEMPLATE_DIR/conf/modutils.patch-gcc4"
PACKAGE_CONFIG_FILE_MODULE_INIT_TOOLS="$INITRD_TEMPLATE_DIR/conf/module-init-tools.conf"
PACKAGE_CONFIG_FILE_RSYNC="$INITRD_TEMPLATE_DIR/conf/rsync.conf"


if [ -f $INITRD_TEMPLATE_DIR/../../../base/include/qrm-functions ]; then
	. $INITRD_TEMPLATE_DIR/../../../base/include/qrm-functions
	. $INITRD_TEMPLATE_DIR/../../../base/include/qrm-setup-functions
elif [ -f $INITRD_TEMPLATE_DIR/../../include/qrm-functions ]; then
	. $INITRD_TEMPLATE_DIR/../../include/qrm-functions
	. $INITRD_TEMPLATE_DIR/../../include/qrm-setup-functions
else
	echo "ERROR: Could not found qrm-function files"
	exit 1
fi

# checks
if ! which portmap 1>/dev/null 2>&1; then
	echo "ERROR: Could not find portmap binary! Please install portmap and try again"
	exit 1
fi

# functions

function find_lib_deps() {
	local BINARY=$1
	cd $INITRD_TEMPLATE_DIR
	if (( $# != 1 )); then
		echo "Usage $0 [binary]"
		return
	fi
	for COPYLIB in `ldd $BINARY | awk {' print $1 $2 $3 '} | cut -d'(' -f 1`; do
		LIBRARY=`echo $COPYLIB | cut -d'>' -f 2`
		if [ ! -z $LIBRARY ] && [ -f $LIBRARY ]; then
			ALL_LIBRARY=`echo $LIBRARY | cut -d'.' -f 1 | cut -d'-' -f 1`
			LIB_DIR=`dirname $LIBRARY`
			#echo "copying $ALL_LIBRARY"
			mkdir -p $QRM_ROOT_DIR/initroot$LIB_DIR
			if ls $ALL_LIBRARY.* 1>/dev/null 2>&1; then
				/bin/cp -aRf $ALL_LIBRARY.* $QRM_ROOT_DIR/initroot$LIB_DIR
			fi
			if ls $ALL_LIBRARY-* 1>/dev/null 2>&1; then
				/bin/cp -aRf $ALL_LIBRARY-* $QRM_ROOT_DIR/initroot$LIB_DIR
			fi
		elif ! echo $COPYLIB | grep linux-gate 1>/dev/null; then
			echo "WARNING: Could not find required library $COPYLIB"
			sleep 5
		fi
	done
}

# function to check if a device file exist, if not possible create it
function check_device_exist() {
	DEVICE=$1
	DEVICE_NAME=`echo $DEVICE | sed -e "s/\/dev\///"`
	if [ -e $DEVICE ]; then
		return
	elif [ -x /dev/MAKEDEV ]; then
		# echo "Device file $DEVICE does not exist. Creating it now."
		# This is for debian and SuSe
		if [ -f /etc/debian_version ] || [ -f /etc/SuSE-release ] ; then
			# This works for the currently used devices, but won't
			# work for more complicated raid devices (/dev/rd/c0d0p1), etc
			# It will create every device in the class (like /dev/sda[1-10], 
			# rather than one at a time.
			cd /dev
			DEVICE_GROUP=$( echo $DEVICE_NAME | sed -e "s/^\(...\).*/\1/" )
			/dev/MAKEDEV $DEVICE_GROUP
			cd - >/dev/null
		# for Redhat
		else
			/dev/MAKEDEV $DEVICE_NAME
		fi
	else
		echo "WARNING: Missing device file /dev/hd$LETTER$NUMBER"
		echo "Could not create it. /dev/MAKEDEV missing. Please install MAKEDEV."
		sleep 1
	fi
}

# main
echo "creating $QRM_ROOT_DIR/initroot"
CURRENT=`pwd`
cd $INITRD_TEMPLATE_DIR
/bin/rm -rf $QRM_ROOT_DIR/initroot
mkdir -p $QRM_ROOT_DIR/initroot

echo "creating directories"
for DIR in $INITRD_DIRECTORIES; do
	#echo "creating directory $QRM_ROOT_DIR/initroot/$DIR"
	mkdir -p $QRM_ROOT_DIR/initroot/$DIR
done
cd $QRM_ROOT_DIR/initroot
#ln -s bin sbin
cd etc
ln -s /proc/mounts mtab
ln -s rc.d/init.d init.d
touch fstab passwd group
cd $INITRD_TEMPLATE_DIR

echo "creating dev directory"
for DEV in $INITRD_DEVICES_COMMON; do
	/bin/cp -aR /dev/$DEV $QRM_ROOT_DIR/initroot/dev/
done
echo "creating ide hardisk devices"
for LETTER in a b c d; do
	check_device_exist /dev/hd$LETTER
	/bin/cp -aR /dev/hd$LETTER $QRM_ROOT_DIR/initroot/dev/hd$LETTER
	for NUMBER in 1 2 3 4 5 6 7 8 9 10; do
		check_device_exist /dev/hd$LETTER$NUMBER
		/bin/cp -aR /dev/hd$LETTER$NUMBER $QRM_ROOT_DIR/initroot/dev/hd$LETTER$NUMBER
	done
done
echo "creating scsi hardisk devices"
for LETTER in a b c d e f g h i j k l m o p q r s t u v w x y z; do
	check_device_exist /dev/sd$LETTER
	/bin/cp -aR /dev/sd$LETTER $QRM_ROOT_DIR/initroot/dev/sd$LETTER
	for NUMBER in 1 2 3 4 5 6 7 8 9 10; do
		check_device_exist /dev/sd$LETTER$NUMBER
		/bin/cp -aR /dev/sd$LETTER$NUMBER $QRM_ROOT_DIR/initroot/dev/sd$LETTER$NUMBER
	done
done
echo "creating special devices"
mknod $QRM_ROOT_DIR/initroot/$INITRD_DEVICES_ROOT
mknod $QRM_ROOT_DIR/initroot/$INITRD_DEVICES_NFS
mknod $QRM_ROOT_DIR/initroot/$INITRD_DEVICES_PS2

echo "creating bin dir"
for PROGRAM in $INITRD_BINARIES; do
	WHICH_PROGRAM=`which $PROGRAM`
	PROGRAM_DIR=`dirname $WHICH_PROGRAM`
	#echo "copying $WHICH_PROGRAM to $QRM_ROOT_DIR/initroot$PROGRAM_DIR"
	mkdir -p $QRM_ROOT_DIR/initroot$PROGRAM_DIR
	/bin/cp -aR $WHICH_PROGRAM $QRM_ROOT_DIR/initroot$PROGRAM_DIR
	find_lib_deps $WHICH_PROGRAM
done
# be sure to get the libc
/bin/cp -aR /lib/libc.* $QRM_ROOT_DIR/initroot/lib/
/bin/cp -aR /lib/libc-* $QRM_ROOT_DIR/initroot/lib/
cd $CURRENT

# busybox
function busybox_pre_make_cmd() {
	. $PACKAGE_CONFIG_FILE_BUSYBOX
	/bin/cp $INITRD_TEMPLATE_DIR/conf/qrm-busybox.config $QRM_BUILD_DIR/busybox/busybox-${PACKAGE_VERSION}/.config
	make oldconfig
}
function busybox_post_make_cmd() {
	mkdir -p $QRM_CACHE_DIR/initrd
	make PREFIX=$QRM_CACHE_DIR/initrd install
}
QRM_PRE_MAKE_CMD=busybox_pre_make_cmd QRM_POST_MAKE_CMD=busybox_post_make_cmd \
  build_package $PACKAGE_CONFIG_FILE_BUSYBOX

# kudzu
function kudzu_pre_make_cmd() {
	cat >> pci.h <<EOF
#ifndef byte
#define byte unsigned char
#endif
EOF

if grep Valhalla /etc/redhat-release 1>/dev/null 2>&1; then
	echo "patching kudzu for Redhat 7.3"
	/bin/cp pcmcia.c pcmcia.c.org
	cat pcmcia.c | sed -e "s/ADD, IO, 0, .resource.io = { 0x0c00, 0x0100, 0 }/0, 0, 0 /g" \
	| sed -e "s/ADD, IO, 0, .resource.io = { 0x0100, 0x0400, 0 }/0, 0, 0 /g" \
	| sed -e "s/ADD, MEM, 0, .resource.memory = { 0xc0000, 0x40000 }/0, 0, 0 /g" \
	| sed -e "s/ADD, MEM, 0, .resource.memory = { 0x60000000, 0x1000000 }/0, 0, 0 /g" \
	| sed -e "s/ADD, MEM, 0, .resource.memory = { 0xa0000000, 0x1000000 }/0, 0, 0 /g" \
	| sed -e "s/ADD, IO, 0, .resource.io = { 0x0a00, 0x0100, 0 }/0, 0, 0 /g" \
	| sed -e "s/REMOVE, IRQ, 0, .resource.irq = { 4 }/0, 0, 0 /g" \
	| sed -e "s/REMOVE, IRQ, 0, .resource.irq = { 7 }/0, 0, 0 /g" \
	| sed -e "s/REMOVE, IRQ, 0, .resource.irq = { 12 }/0, 0, 0 /g" \
	| sed -e "s/REMOVE, IO, 0, .resource.io = { 0x380, 0x080, 0 }/0, 0, 0 /g" \
	> pcmcia.c.new
	/bin/mv pcmcia.c.new pcmcia.c
fi

}
function kudzu_post_make_cmd() {
	mkdir -p $QRM_ROOT_DIR/include/
	/bin/cp *.h $QRM_ROOT_DIR/include/
}
QRM_MAKE_OPTIONS="libkudzu.a" QRM_PRE_MAKE_CMD=kudzu_pre_make_cmd QRM_POST_MAKE_CMD=kudzu_post_make_cmd \
  build_package $PACKAGE_CONFIG_FILE_KUDZU
	install -D $QRM_CACHE_DIR/kudzu/libkudzu.a $QRM_ROOT_DIR/lib/libkudzu.a

# hwsetup
function hwsetup_pre_make_cmd() {
	cat > Makefile <<EOF
all:
	gcc -Wall -fPIC -O2 -s -o hwsetup hwsetup.c -I$QRM_ROOT_DIR/include -L$QRM_ROOT_DIR/lib -lkudzu -lpci -static
EOF
}
QRM_PRE_MAKE_CMD=hwsetup_pre_make_cmd \
  build_package $PACKAGE_CONFIG_FILE_HWSETUP
install -D $QRM_CACHE_DIR/hwsetup/hwsetup $QRM_CACHE_DIR/initrd/bin/hwsetup

# hwdata
. $PACKAGE_CONFIG_FILE_HWDATA
HWDATA_FILES="CardMonitorCombos Cards MonitorsDB pci.ids pcitable upgradelist usb.ids"
HWDATA_PKG=`qrm_cache URL $FILE $SOURCE`
if [ "$HWDATA_PKG" == "UNSUCCESSFULL" ]; then
	echo "ERROR: Could not download Qrm-component hwdata"
	exit 1
fi
for CFILE in $HWDATA_FILES; do 
	HWDATA_FILES1="*/$CFILE $HWDATA_FILES1"
done
mkdir -p $QRM_CACHE_DIR/initrd/usr/share
rm -rf $QRM_CACHE_DIR/initrd/usr/share/hwdata
tar -C $QRM_CACHE_DIR/initrd/usr/share -zxf $HWDATA_PKG $HWDATA_FILES1
mv $QRM_CACHE_DIR/initrd/usr/share/hwdata-* $QRM_CACHE_DIR/initrd/usr/share/hwdata

# ddcxinfo
QRM_MAKE_OPTIONS="ddcxinfo-knoppix"
build_package $PACKAGE_CONFIG_FILE_DDCXINFO
/bin/cp -f $QRM_CACHE_DIR/ddcxinfo/ddcxinfo-knoppix $QRM_CACHE_DIR/initrd/bin/  

# xf86config
. $PACKAGE_CONFIG_FILE_XF86CONFIG
XF86CONFIG_PKG=`qrm_cache URL $FILE $SOURCE`
if [ "$XF86CONFIG_PKG" == "UNSUCCESSFULL" ]; then
	echo "ERROR: Could not download Qrm-component xf86config"
	exit 1
fi
XF86CONFIG_FILES="mkxf86config.sh XF86Config-4.in XF86Config.in"
for CFILE in $XF86CONFIG_FILES; do 
	XF86CONFIG_FILES1="*/$CFILE $XF86CONFIG_FILES1"
done
mkdir -p $QRM_CACHE_DIR/initrd/etc
rm -rf $QRM_CACHE_DIR/initrd/etc/X11
tar -C $QRM_CACHE_DIR/initrd/etc -zxf $XF86CONFIG_PKG $XF86CONFIG_FILES1
mv $QRM_CACHE_DIR/initrd/etc/xf86config-knoppix-* $QRM_CACHE_DIR/initrd/etc/X11
mv $QRM_CACHE_DIR/initrd/etc/X11/mkxf86config.sh $QRM_CACHE_DIR/initrd/bin/

# e2fsprogs
QRM_MAKE_OPTIONS="LDFLAGS=-static"
QRM_CONFIGURE_OPTIONS="LDFLAGS=-static"
build_package $PACKAGE_CONFIG_FILE_E2FSPROGS
cp -f $QRM_CACHE_DIR/e2fsprogs/misc/mke2fs $QRM_CACHE_DIR/initrd/bin/

# depmod.old + depmod

# modutils / depmod.old
function modutils_pre_make_cmd() {
	# patch for gcc >= 4.x
	if gcc --version | head -n 1 | awk {' print $3 '} | grep "^4.*" 1>/dev/null; then
		echo "Patching the modutils for gcc >= 4.x"
		patch -p0 < $PACKAGE_PATCH_FILE_MODUTILS
	fi
}

function modutils_post_make_cmd() {
	cd depmod
	rm -f depmod
	gcc -O2 -Wall -o depmod depmod.o depmod_64.o ../util/libutil.a ../obj/libobj.a --static
	cp -f depmod depmod.old
	cd ..
}

QRM_PRE_MAKE_CMD="modutils_pre_make_cmd"	\
QRM_POST_MAKE_CMD="modutils_post_make_cmd"	\
	build_package $PACKAGE_CONFIG_FILE_MODUTILS
cp -f $QRM_CACHE_DIR/modutils/depmod/depmod.old $QRM_CACHE_DIR/initrd/bin/


# module-init-tools / new depmod
function module_init_tools_post_make_cmd() {
	rm -f depmod
	gcc  -g -O2 -Wunused -Wall   -o depmod  depmod.o moduleops.o tables.o zlibsupport.o --static
}
QRM_MAKE_OPTIONS="depmod"	\
QRM_POST_MAKE_CMD="module_init_tools_post_make_cmd"	\
	build_package $PACKAGE_CONFIG_FILE_MODULE_INIT_TOOLS
cp -f $QRM_CACHE_DIR/module-init-tools/depmod $QRM_CACHE_DIR/initrd/bin/


# rsync
QRM_MAKE_OPTIONS="LD_FLAGS=--static"	\
build_package $PACKAGE_CONFIG_FILE_RSYNC
cp -f $QRM_CACHE_DIR/rsync/rsync $QRM_CACHE_DIR/initrd/bin/

cd $INITRD_TEMPLATE_DIR

cp -a $QRM_CACHE_DIR/initrd/* $QRM_ROOT_DIR/initroot/

# create rcS
cat >> $QRM_ROOT_DIR/initroot/etc/rc.d/init.d/rcS << EOF
#!/bin/bash
export SHELL=/bin/bash
echo "starting rcS"

if [ -f /reboot ]; then
 echo "rebooting now"
 /sbin/reboot
fi

EOF
chmod +x $QRM_ROOT_DIR/initroot/etc/rc.d/init.d/rcS

# create inittab
cat >> $QRM_ROOT_DIR/initroot/etc/inittab << EOF

# inittab
::askfirst:-/bin/bash
tty2::askfirst:-/bin/bash
tty3::askfirst:-/bin/bash
tty4::askfirst:-/bin/bash
::sysinit:/etc/init.d/rcS
::restart:/sbin/init

# Stuff to do before rebooting
::ctrlaltdel:/sbin/qrm_save_reboot
::shutdown:/sbin/qrm_save_halt

EOF

cd $QRM_ROOT_DIR/initroot
/bin/rm -f linuxrc ../initrd-qrm.tgz
tar -czf ../initrd-qrm.tgz *
cd ..
/bin/rm -rf $QRM_ROOT_DIR/initroot
echo "qrm-initrd template created at : `pwd`/initrd-qrm.tgz"
cd $CURRENT
