#!/bin/bash
#Automatically Created by slkbuild 0.5.1
#Maintainer: JRD <jrd@enialis.net>

######Begin Redundant Code######################################
check_for_root() {
	if [ "$UID" != "0" ]; then
		echo "You need to be root"
		exit 1
	fi
}

clean_dirs () {
        for COMPLETED in src pkg; do
                if [ -e $COMPLETED ]; then
                        rm -rf $COMPLETED
                fi
        done
}

clean_old_builds () {
	rm -rf $package.{t[xlgb]z,md5}
	clean_dirs
}

set_pre_permissions() {
	cd $startdir/src
	find . -perm 664 -exec chmod 644 {} \;
	find . -perm 600 -exec chmod 644 {} \;
	find . -perm 444 -exec chmod 644 {} \;
	find . -perm 400 -exec chmod 644 {} \;
	find . -perm 440 -exec chmod 644 {} \;
	find . -perm 777 -exec chmod 755 {} \;
	find . -perm 775 -exec chmod 755 {} \;
	find . -perm 511 -exec chmod 755 {} \;
	find . -perm 711 -exec chmod 755 {} \;
	find . -perm 555 -exec chmod 755 {} \;
}


gzip_man_and_info_pages() {
	for DOCS in man info; do
		if [ -d "$startdir/pkg/usr/share/$DOCS" ]; then
			mv $startdir/pkg/usr/share/$DOCS $startdir/pkg/usr/$DOCS
			if [[ ! "$(ls $startdir/pkg/usr/share)" ]]; then
				rm -rf $startdir/pkg/usr/share
			fi
		fi
		if [ -d "$startdir/pkg/usr/$DOCS" ]; then
			# I've never seen symlinks in info pages....
			if [ "$DOCS" == "man" ]; then
				(cd $startdir/pkg/usr/$DOCS
				for manpagedir in $(find . -type d -name "man*" 2> /dev/null) ; do
					( cd $manpagedir
					for eachpage in $( find . -type l -maxdepth 1 2> /dev/null) ; do
						ln -s $( readlink $eachpage ).gz $eachpage.gz
						rm $eachpage
					done )
				done)
			fi
			find $startdir/pkg/usr/$DOCS -type f -exec gzip -9 '{}' \;
		fi
	done
	[ -a $startdir/pkg/usr/info/dir.gz ] && rm -f $startdir/pkg/usr/info/dir.gz
}

set_post_permissions() {
	for DIRS in usr/share/icons usr/doc; do
		if [ -d "$startdir/pkg/$DIRS" ]; then
			if [ "$DIRS" == "usr/doc" ]; then
				find $startdir/pkg/$DIRS -type f -exec chmod 644 {} \;
				find $startdir/pkg/$DIRS -type d -exec chmod 755 {} \;
			fi
		fi
		[ -d $startdir/pkg/$DIRS ] && chown root:root -R $startdir/pkg/$DIRS
	done
	[ -d $startdir/pkg/usr/bin ] && find $startdir/pkg/usr/bin -user root -group bin -exec chown root:root {} \;
}

copy_build_script() {
	mkdir -p $startdir/pkg/usr/src/$pkgname-$pkgver/
	cp $startdir/build-$pkgname.sh $startdir/pkg/usr/src/$pkgname-$pkgver/build-$pkgname.sh
	[ -f $startdir/SLKBUILD ] && cp $startdir/SLKBUILD	$startdir/pkg/usr/src/$pkgname-$pkgver/SLKBUILD
}

create_package() {
	ls -lR $startdir/pkg
	cd $startdir/pkg
	/sbin/makepkg -l y -c n $startdir/$package.txz
	cd $startdir
	md5sum $package.txz > $startdir/$package.md5
}

strip_binaries() {
	cd $startdir/pkg
	find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | \
	xargs strip --strip-unneeded 2> /dev/null
	find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | \
	xargs strip --strip-unneeded 2> /dev/null
}
#########End Redundant Code#####################################
#########Begin Non Redundant Code##############################

prepare_directory() {
	mkdir $startdir/src
	mkdir -p $startdir/pkg/usr/src/$pkgname-$pkgver
	for SOURCES in ${source[@]}; do
		protocol=$(echo $SOURCES | sed 's|:.*||')
	        file=$(basename $SOURCES | awk -F= '{print $NF}')
		if [ ! -f "$file" ]; then
			if [ "$protocol" = "http" -o "$protocol" = "https" -o "$protocol" = "ftp" ]; then
				echo -e "\nDownloading $(basename $SOURCES)\n"
        	                wget $SOURCES -O $file
				if [ ! "$?" == "0" ]; then
					echo "Download failed"
					exit 2
				fi 
			else
				echo "$SOURCES does not appear to be a url nor is it in the directory"
				exit 2
			fi
		fi
		cp -R $file $startdir/src
		if ! [ "$protocol" = "http" -o "$protocol" = "https" -o "$protocol" = "ftp" ]; then
			cp -R $startdir/$(basename $SOURCES) $startdir/pkg/usr/src/$pkgname-$pkgver/
		fi
	done
}

extract_source() {
	cd $startdir/src
	if [[ "$(ls $startdir/src)" ]]; then	
		for FILES in ${source[@]}; do
	        	FILES="$(basename $FILES | awk -F= '{print $NF}')"
			file_type=$(file -biz "$FILES")
			unset cmd
			case "$file_type" in
				*application/x-tar*)
					cmd="tar -xf" ;;
				*application/x-zip*)
					cmd="unzip" ;;
				*application/zip*)
					cmd="unzip" ;;
				*application/x-gzip*)
					cmd="gunzip -d -f" ;;
				*application/x-bzip*)
					cmd="bunzip2 -f" ;;
				*application/x-xz*)
					cmd="xz -d -f" ;;
				*application/x-lzma*)
					cmd="lzma -d -f" ;;
			esac
			if [ "$cmd" != "" ]; then
				echo "$cmd $FILES"
	        	        $cmd $FILES
			fi
		done
	elif [ ! "$source" ]; then
		echo -n "" # lame fix
	else
		echo "no files in the src directory $startdir/src"
		exit 2
	fi
}

build() {
  export KVEREXTRA=$(uname -r)
  export KVER=$(echo $KVEREXTRA|sed 's/\(.*\)-.*/\1/')
  export SRC=$startdir/src
  export DEST=$startdir/pkg
  # clone the kernel
  echo '########################################'
  echo "Cloning /usr/src/linux-$KVER..."
  echo '########################################'
  cp -a /usr/src/linux-$KVER $SRC/linuxsrc || exit 1
  cd $SRC/linuxsrc
  # clean the kernel
  make mrproper || exit 1
  echo '* Applying aufs2-standalone.patch... *'
  # patch the kernel to use a new FS : aufs (an unionfs like filesystem)
  patch -p1 < $SRC/aufs2-standalone/aufs2-standalone.patch || exit 1
  if [ -e $SRC/aufs2-standalone/aufs2-base.patch ]; then
    echo '* Applying aufs2-base.patch... *'
    patch -p1 < $SRC/aufs2-standalone/aufs2-base.patch || exit 1
  fi
  # patch the kernel to use a specific squashfs FS : this one could use a compression algorithm
  # We must first remove the squashfs 4.0 code without LZMA and then use the squashfs 3.4 which
  # has patches for LZMA
  sed 's/4\.0/3.4/' fs/squashfs/Kconfig > squashfs-Kconfig
  rm -r fs/squashfs/*
  mv squashfs-Kconfig fs/squashfs/Kconfig
  echo '* Applying squashfs3.4-patch... *'
  patch -p1 < $SRC/squashfs3.4/kernel-patches/linux-2.6.30/squashfs3.4-patch || exit 1
  echo '* Applying sqlzma2k-3.4.patch...*'
  # patch for squashfs 3.4
  patch -p1 < $SRC/sqlzma2k-3.4.patch || exit 1
  cp $SRC/sqlzma.h $SRC/sqmagic.h fs/squashfs/
  # squashfs-tools is already patched to be aware of LZMA
  # LZMA is already patched to build a kernel module
  # install the AUFS code in the kernel
  cp -r $SRC/aufs2-standalone/fs/aufs $SRC/linuxsrc/fs/
  cp $SRC/aufs2-standalone/include/linux/aufs_type.h $SRC/linuxsrc/include/linux/
  echo '* Applying aufs2-kbuild.patch... *'
  patch -p1 < $SRC/aufs2-standalone/aufs2-kbuild.patch || exit 1
  # use a suitable configuration for live environnement.
  cp $SRC/config-$KVEREXTRA.live .config
  make oldconfig scripts prepare || exit 1
  # compile the kernel (without squashfs for now)
  echo '########################################'
  echo "Compiling modules..."
  echo '########################################'
  make -j 3 modules || exit 1
  echo '########################################'
  echo "Compiling kernel image..."
  echo '########################################'
  make -j 3 bzImage || exit 1
  export INSTALL_MOD_PATH=$DEST
  echo '########################################'
  echo "Installing modules..."
  echo '########################################'
  make modules_install || exit 1
  # now compile the squashfs+lzma modules
  cd $SRC
  echo '########################################'
  echo "Compiling/installing squashfs + LZMA..."
  echo '########################################'
  make || exit 1
  unset INSTALL_MOD_PATH
  # create the good structure for the modules
  cd $DEST/lib/modules/$KVEREXTRA-live
  rm -f modules.*
  mkdir -p kernel/fs/squashfs
  cp $SRC/lzma457/C/Compress/Lzma/kmod/{sq,un}lzma.ko kernel/fs/squashfs/
  cp $SRC/linuxsrc/fs/squashfs/squashfs.ko kernel/fs/squashfs/
  # copy the kernel
  cd $DEST
  mkdir -p boot
  cd boot
  cp $SRC/linuxsrc/.config config-$KVEREXTRA-live
  cp $SRC/linuxsrc/System.map System.map-$KVEREXTRA-live
  cp $SRC/linuxsrc/arch/x86/boot/bzImage vmlinuz-$KVEREXTRA-live
  ln -s config-$KVEREXTRA-live config
  ln -s System.map-$KVEREXTRA-live System.map
  ln -s vmlinuz-$KVEREXTRA-live vmlinuz
  cd ..
  # create rc.modules
  mkdir -p etc/rc.d
  cat << EOF > etc/rc.d/rc.modules
#!/bin/sh
# rc.modules   $(date) <Generated by kernelive>
#
# This file loads extra drivers into the Linux kernel.
# As kmod and udev handle module loading, this file will be mostly
# commented out, but is still useful for loading selected modules at boot time.
#

RELEASE=\$(uname -r)

echo "Updating module dependencies for Linux \$RELEASE"

/sbin/depmod -A

EOF
  sed -e "s@_ROOT_@$DEST@ ; s/_KVER_/${KVEREXTRA}-live/" $SRC/modules.conf > $DEST/modules.conf
  export MODULECONF=$DEST/modules.conf
  depmod -a -b $DEST -F $DEST/boot/System.map $KVEREXTRA-live || exit 1
  modprobe -l | sed -e "s/^.*\/\(.*\)\.ko$/# \/sbin\/modprobe \1/m ; s/# \(.* ac$\)/\1/ ; s/# \(.* battery$\)/\1/ ; s/# \(.* button$\)/\1/ ; s/# \(.* fan$\)/\1/ ; s/# \(.* fuse$\)/\1/ ; s/# \(.* processor$\)/\1/ ; s/# \(.* thermal$\)/\1/ ; s/# \(.* video$\)/\1/ ; s/# \(.* lp$\)/\1/ ; s/# \(.* parport$\)/\1/ ; s/# \(.* parport_pc$\)/\1/ " | sort >> etc/rc.d/rc.modules
  chmod 755 etc/rc.d/rc.modules
  rm -rf $DEST/modules.conf $DEST/persist
  unset MODULECONF
  # copy files necessary for later builds, like nvidia and vmware
  cd $SRC/linuxsrc/include
  mkdir -p $DEST/usr/src/linux-$KVER/include
  for i in acpi asm-generic asm-x86 linux math-emu media net pcmcia scsi sound video; do
    cp -rf $i $DEST/usr/src/linux-$KVER/include/
  done
  ( cd $DEST/usr/src/linux-$KVER/include; ln -sf asm-x86 asm )
  ( cd $DEST/usr/src/linux-$KVER/include/linux; ln -sf autoconf.h config.h )
  cd $SRC/linuxsrc
  cp .config $DEST/usr/src/linux-$KVER
  cp Makefile ${dest}/usr/src/linux-$KVER
  cp Module.symvers $DEST/usr/src/linux-$KVER
  cp -a scripts $DEST/usr/src/linux-$KVER
  # fix permissions on scripts dir
  chmod 755 -R $DEST/usr/src/linux-$KVER/scripts
  mkdir -p $DEST/usr/src/linux-$KVER/.tmp_versions
  mkdir -p $DEST/usr/src/linux-$KVER/arch/x86/kernel
  cp arch/x86/Makefile* $DEST/usr/src/linux-$KVER/arch/x86/
  cp arch/x86/kernel/asm-offsets.s $DEST/usr/src/linux-$KVER/arch/x86/kernel/
  # add headers for lirc package
  mkdir -p $DEST/usr/src/linux-$KVER/drivers/media/video
  cp drivers/media/video/*.h  $DEST/usr/src/linux-$KVER/drivers/media/video/
  for i in bt8xx cpia2 cx25840 cx88 em28xx et61x251 pwc saa7134 sn9c102 usbvideo zc0301; do
    mkdir -p $DEST/usr/src/linux-$KVER/drivers/media/video/$i
    cp -a drivers/media/video/$i/*.h $DEST/usr/src/linux-$KVER/drivers/media/video/$i
  done
  # add dm headers
  mkdir -p $DEST/usr/src/linux-$KVER/drivers/md
  cp drivers/md/*.h $DEST/usr/src/linux-$KVER/drivers/md
  # add inotify.h
  mkdir -p $DEST/usr/src/linux-$KVER/include/linux
  cp include/linux/inotify.h $DEST/usr/src/linux-$KVER/include/linux/
  # add wireless headers
  mkdir -p $DEST/usr/src/linux-$KVER/net/mac80211/
  cp net/mac80211/*.h $DEST/usr/src/linux-$KVER/net/mac80211/
  # add CLUSTERIP file for iptables
  mkdir -p $DEST/usr/src/linux-$KVER/net/ipv4/netfilter/
  cp net/ipv4/netfilter/ipt_CLUSTERIP.c $DEST/usr/src/linux-$KVER/net/ipv4/netfilter/
  # add xfs and shmem for aufs building
  mkdir -p $DEST/usr/src/linux-$KVER/fs/xfs
  mkdir -p $DEST/usr/src/linux-$KVER/mm
  cp fs/xfs/xfs_sb.h $DEST/usr/src/linux-$KVER/fs/xfs/xfs_sb.h
  cp mm/shmem.c $DEST/usr/src/linux-$KVER/mm/shmem.c
  # add vmlinux
  cp vmlinux $DEST/usr/src/linux-$KVER  
  # copy in Kconfig files
  for i in `find . -name "Kconfig*"`; do 
    mkdir -p $DEST/usr/src/linux-$KVER/`echo $i | sed 's|/Kconfig.*||'`
    cp $i $DEST/usr/src/linux-$KVER/$i
  done
  # fix build and source link in /lib/modules/XXX/
  cd $DEST/lib/modules/$KVEREXTRA-live/
  rm -f build && ln -s /usr/src/linux-$KVER build
  rm -f source && ln -s /usr/src/linux-$KVER source
} 

create_slackdesc() {
mkdir $startdir/pkg/install
cat <<"EODESC" >$startdir/pkg/install/slack-desc
kernelive: kernelive (Linux kernel for Salix Live)
kernelive: 
kernelive: Linux kernel for Salix Live is compiled with support for
kernelive: squashfs, lzma & aufs as well as for most hardware, 
kernelive: including SCSI, USB booting devices, etc.. 
kernelive: 
kernelive: Drivers (such as for CD-ROM drives on proprietary interfaces,
kernelive: or ethernet cards) may be loaded as modules.
kernelive: See /etc/rc.d/rc.modules for examples
kernelive: 
kernelive: 
EODESC
}

copy_docs() {
	for stuff in ${docs[@]}; do
		if [ ! -d "$startdir/pkg/usr/doc/$pkgname-$pkgver" ]; then
			mkdir -p $startdir/pkg/usr/doc/$pkgname-$pkgver
		fi
		find $startdir/src -type f -iname "$stuff" -exec cp -R '{}' $startdir/pkg/usr/doc/$pkgname-$pkgver \;
	done
}
create_source_file(){
	[ -f $package.src ] && rm $package.src
	if [ ! -z $sourcetemplate ]; then
		echo $sourcetemplate/SLKBUILD >> $package.src
		echo $sourcetemplate/build-$pkgname.sh >> $package.src
		for SOURCES in ${source[@]}; do
			protocol=$(echo $SOURCES | sed 's|:.*||')
			if ! [ "$protocol" = "http" -o "$protocol" = "https" -o "$protocol" = "ftp" ]; then
				if [ ! -z $sourcetemplate ]; then
					echo $sourcetemplate/$(basename $SOURCES) >> $package.src
				else
					echo $(basename $SOURCES) >> $package.src
				fi
			else
				echo $SOURCES >> $package.src
			fi
		done
	fi
}
post_checks(){
	# Ideas taken from src2pkg :)
	if [ -d "$startdir/pkg/usr/doc/$pkgname-$pkgver" ]; then
		for DIRS in usr/doc/$pkgname-$pkgver usr/doc; do
			cd $startdir/pkg/$DIRS
			if [[ $(find . -type f) = "" ]] ; then
				cd ..
				rmdir $DIRS
			fi
		done
	fi
	# if the docs weren't deleted ...
	if [ -d "$startdir/pkg/usr/doc/$pkgname-$pkgver" ]; then
		cd $startdir/pkg/usr/doc/$pkgname-$pkgver
		#remove zero lenght files
		if [[ $(find . -type f -size 0) ]]; then
			echo "Removing some zero lenght files"
			find . -type f -size 0 -exec rm -f {} \;
		fi
	fi
	# check if we need to add code to handle info pages
	if [[ -d $startdir/pkg/usr/info ]] && [[ ! $(grep install-info $startdir/pkg/install/doinst.sh &> /dev/null) ]] ; then
		echo "Found info files - Adding install-info command to doinst.sh"
		INFO_LIST=$(ls -1 $startdir/pkg/usr/info)
		echo "" >> $startdir/pkg/install/doinst.sh
		echo "if [ -x usr/bin/install-info ] ; then" >> $startdir/pkg/install/doinst.sh
		for page in $(echo $INFO_LIST) ; do
			echo " usr/bin/install-info --info-dir=usr/info usr/info/$page 2>/dev/null" >> $startdir/pkg/install/doinst.sh
		done
		echo "fi" >> $startdir/pkg/install/doinst.sh
	fi
	[[ -e $startdir/pkg/usr/info/dir ]] && rm -f $startdir/pkg/usr/info/dir

	if [ -d $startdir/pkg/etc ]; then
		cd $startdir/pkg/
		for conf in $(find ./etc -type f) ; do
			conf=${conf: 2}
			dotnew=( "${dotnew[@]}" "$conf" )
		done
	fi
	if [[ "$dotnew" ]]; then
        for files in ${dotnew[@]} ; do
                fullfile="${startdir}/pkg/${files}"
                if [ -e "$fullfile" ]; then
                        mv $fullfile ${fullfile}.new
                else
                        echo "$fullfile was not found"
                        exit 2
                fi
        done
        cat<<"EODOTNEW" >>$startdir/pkg/install/doinst.sh
#Added by slkbuild 0.5.1
dotnew() {
        NEW="${1}.new"
        OLD="$1"
        if [ ! -e $OLD ]; then
                mv $NEW $OLD
        elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
                rm $NEW
        fi
}
EODOTNEW
for i in ${dotnew[@]}; do
echo "dotnew $i" >> $startdir/pkg/install/doinst.sh
done
fi
}

####End Non Redundant Code############################

#Variables

startdir=$(pwd)
SRC=$startdir/src
PKG=$startdir/pkg

pkgname=kernelive
pkgver=2.6.29.6.smp
pkgrel=1cp
arch=i486
package=$pkgname-$pkgver-$arch-1cp
source=("config-2.6.29.6-smp.live" "config-2.6.29.6-smp.live.patch" "aufs2-standalone.tar.gz" "squashfs3.4.tgz" "lzma457.tgz" "sqlzma2k-3.4.patch" "sqlzma.h" "sqmagic.h" "modules.conf" "Makefile")
sourcetemplate=http://enialis.net/~jrd/salix/kernelive/2.6.29.6.smp-1cp/
docs=(readme copying sqlzma.txt)
export CFLAGS="-O2 -march=i486 -mtune=i686"
export CXXFLAGS="-O2 -march=i486 -mtune=i686"

#Execution

check_for_root
clean_old_builds
prepare_directory
extract_source
set_pre_permissions
build
if [ ! "$?" = "0" ]; then
	echo "build() failed."
	exit 2
fi
create_slackdesc
post_checks
copy_docs
strip_binaries
gzip_man_and_info_pages
set_post_permissions
copy_build_script
create_package
create_source_file
echo "Package has been built."
echo "Cleaning pkg and src directories"
clean_dirs

