All pastes #149750 Raw Edit

Something

public text v1 · immutable
#149750 ·published 2006-08-26 02:47 UTC
rendered paste body
#!/bin/sh

###############################################################################
##
#   mkliveiso - make live iso image, using squashfs+unionfs for r/w fs
#   coded by Elia Yehuda, aka z4ziggy, and Phil Dillon-Thiselton, aka dtw, 2005-2006
#   
#   Copyright (c) 2002-2006 by Elia Yehuda <z4ziggy+at+user-contributions+dot+org>
#
#   For Arch Linux only - using Arch Linux tools (pacman) and init scripts
#
#
#   TODO
#   readahead (rc.sysinit)
#   search for boot device via kernel/bios instead of searching for boot-cd (linuxrc)
# 
#   overview: TODO
#
##
###############################################################################

version=0.6

. /etc/rc.conf
. /etc/rc.d/functions
. /usr/share/archie/archie.conf
module_list=`ls /etc/archie/modules/`

###############################################################################
# functions and wrappers
###############################################################################

usage()
{
	echo "Usage: "
	echo "  mkliveiso [options] <target>"
	echo
	echo "  <target>                  = the target partition/imagefile to use as live root"
	echo
	echo "Options:"
	echo "  --help                    = display this help message"
	echo "  --quiet                   = quiet mode"
	echo "  --installarch             = install Arch base from scratch on <target>"
	echo "                              (DANGEROUS! will format <target> !!!)"
	echo "  --install2arch <pkg(s)>   = install <package(s)> to target Arch system"
	echo "  --install2iso <pkg(s)>    = install <package(s)> to live Arch system only"
	echo "  --buildiso <isotype>      = build customized Archie iso (`echo $module_list`)"
	echo "  --gfx <gfxtype>           = select gfx from (dri/nvidia/nvidia_legacy/ati)"
	echo "                              If no option is given gfx are auto-detected at startup"
	echo "  --ignoredirs <path(s)>    = ignore path(s) from final iso"
	echo "  --archieconf <path>       = use alternate path for Archie configuration files"
	echo "  --extrarepos <repo(s)>    = extra pacman repositories to use with pacman"
	echo "  --syncpacman              = synchronize pacman repositories (pacman -Sy)"
	echo "  --tmp                     = use /tmp while creating archie iso"
	echo "  --nosplash                = dont install gensplash"
	echo "  --nousb                   = dont include usb modules in initram.gz"
	echo "  --nofirewire              = dont include firewire modules in initram.gz"
	echo "  --splashtheme <name>      = use alternate gensplash theme <name> (default: $splashtheme)"
	echo "  --saveas <filename>       = save iso as <path>/<filename> (default: ./$isoname)"
#	echo "  --blocksize <size>        = squashfs blocksize to use in Kb (default: $blocksize)"
	echo
	exit
}

cleanup()
{
	stat_busy "Cleaning up"
	
# 	# making sure we dont have mounts hanging from pacman_remote() procedure
# 	umount $pacmanpkg
# 	for pacdir in `ls $pacmanlib`; do
# 		[ "$pacdir" != "local" ] && [ -d $pacmanlib/$pacdir ] && umount $1/$pacmanlib/$pacdir
# 	done

	# to be on the safe side we umount $workdir/archieroot in case its mounted
	umount $workdir/archieroot >/dev/null 2>&1
	# and free unionfs module
	modprobe -r unionfs >/dev/null 2>&1

	# now we can start with releasing mounts
	umount $archroot >/dev/null 2>&1

	# scan for hanging mounts...
	HANGMOUNTS=`awk '/$workdir/{print $2}' /proc/mounts`
	if [ ! -z "$HANGMOUNTS" ]; then
		# lets try to umount hanging mounts before giving up
		for mntpoint in $HANGMOUNTS; do umount $mntpoint ; done
		HANGMOUNTS=`awk '/$workdir/{print $2}' /proc/mounts`
	fi

	if [ -z "$HANGMOUNTS" ]; then
		[ -d $workdir ] && rm -r $workdir
		stat_done
	else
		# if nothing worked and we still have hanging mounts, inform the user
		stat_fail
		printhl "Cant remove $workdir - hanging mounts found : $HANGMOUNTS"
	fi
}

fail()
{
	#printhl "oops, error occured, abandoning ship..."
	echo -e "$C_OTHER$PREFIX_HL ${C_FAIL}Oops, an error occured, abandoning ship...$C_CLEAR "
	cleanup
	exit
}

# a better wrapper for pacman to install into a remote location. it uses current Arch 
# packages repository instead of targets' repository, by mounting targets' directories 
# into current Arch directories. using this wrapper (hopefully) eliminates pacman mounts 
# hanging when mkliveiso fails...
pacman_remote()
{
	[ -d $1/$pacmanpkg ] || mkdir -p $1/$pacmanpkg
	mount --bind $pacmanpkg $1/$pacmanpkg

	for pacdir in `ls $pacmanlib`; do
		[ "$pacdir" = "local" ] || [ ! -d $pacmanlib/$pacdir ] && continue
		[ -d $1/$pacmanlib/$pacdir ] || mkdir -p $1/$pacmanlib/$pacdir
		mount --bind $pacmanlib/$pacdir $1/$pacmanlib/$pacdir
	done

	pacman -S --noconfirm -r $*
	pacman_result=$?
	
	umount $1/$pacmanpkg
	for pacdir in `ls $pacmanlib`; do
		[ "$pacdir" != "local" ] && [ -d $pacmanlib/$pacdir ] && umount $1/$pacmanlib/$pacdir
	done
	return $pacman_result
}

scan_parameters()
{
	# format the parameters...
	set -- "$@"
	# check for command line parameter(s)
	[ -z "$1" ] && [ -z "$target" ] && usage
	# getting command line parameter(s)
	while [ "$#" -gt "0" ]; do
		case "$1" in
			--help)
				usage
				;;
			--quiet)
				quiet="yes"
				;;
			--tmp)
				usetmp="yes"
				;;
			--archieconf)
				[ ! -d "$2" ] && usage
				archieconf="$2"
				[ -z "$archieconf" ] && archieconf=`pwd`
				#. $archieconf/archie.conf
				shift
				;;
			--saveas)
				isoname=${2}
				shift
				;;
			--ignoredirs)
				ignoredirs="$2"
				shift
				;;
			--buildiso)
				buildiso="$2"
				count=0
				for iso in $module_list ; do
					if [ "$buildiso" == "$iso" ] ; then
						count=$(($count + 1))
					fi
				done
				if [ "$count" -lt "1" ] ; then
					printhl "unknown Archie iso-type: $buildiso (only `echo $module_list` are supported)"
					exit
				else
					shift
				fi
				;;
			--install2arch)
				install2arch="$2"
				shift
				;;
			--install2iso)
				install2iso="$2"
				shift
				;;
			--extrarepos)
				extrarepos="$2"
				shift
				;;
			--nofirewire)
				copyfirewire="no"
				;;
			--nousb)
				copyusb="no"
				;;
			--installarch)
				installarch="yes"
				;;
			--nosplash)
				installsplash="no"
				;;
			--splashtheme)
				if [ ! -f $splashthemesdir/$2/$splashres.cfg ];then
					printhl "could not find gensplash theme '$2' for resolution $splashres. using default instead."
				else
					splashtheme="$2"
				fi
				shift
				;;
			--syncpacman)
				syncpacman="yes"
				;;
			--gfx)
				gfx="$2"
				if [ -z "$gfx" ] ; then
					gfx="auto"
				else
					eval gfxpkgs=\$gfx_$gfx
				fi
				case $gfx in 
					dri|nvidia|nvidia_legacy|ati|auto) shift; ;;
					*) printhl "unknown GFX type: $gfx (only dri/nvidia/nvidia_legacy/ati are supported)"; exit; ;;
				esac
				;;
			*)
				if [ ! -b "$1" ] && [ ! -f "$1" ]; then
					printhl "unknown parameter or invalid partition/imagefile name: '$1'"
					usage
					exit
				fi
				target="$1"
				[ -f $target ] && rootparam="-o loop" || rootparam=""
				;;
		esac
		shift
	done
}

check_repositories()
{
	# checking for [archie], [unstable] and [community] repositories in /var/lib/pacman amd pacman.conf
	repositories="archie unstable community ${extrarepos}"
	for repo in ${repositories}; do
		if [ ! "$(egrep /$repo /etc/pacman.conf | grep -v "#")" ] && [ ! "$(grep "\[$repo\]" /etc/pacman.conf)" ]; then
			echo "Could not find [$repo] local repository. make sure you've added [$repo]"
			echo "repository to your /etc/pacman.conf"
			echo
			return 1
		fi
		if [ ! -d $pacmanlib/$repo ]; then
			echo "Could not find [$repo] local repository. make sure you've executed 'pacman -Sy'"
			echo
			return 1
		fi
	done
}

check_unionfs()
{
	# make sure we have unionfs ready
	if [ $(zcat /proc/config.gz | grep CONFIG_UNION_FS=y) ]; then
		return 0
	elif [ $(modprobe -l | grep unionfs.ko) ]; then
		modprobe -f unionfs
		if [ $? -ne 0 ] ; then
			echo "  : Failed to insert unionfs module.  Please check your configuration."
			echo "  : Check 'dmesg | tail' for further information."
			return 1
		fi
	else
		echo "  : The kernel you are running does not appear to have unionfs enabled."
		echo "  : Please install the appropriate unionfs module pkg for your kernel"
		echo "  : or install the unionfs-auto pkg (pacman -S unionfs-auto) to"
		echo "  : build and install the module for your kernel"
		return 1
	fi
}

init_archie()
{
	# since not everyone has a huge memory (*cough*), we using temp folder in directory
	if [ "$usetmp" = "yes" ]; then
		workdir=/tmp/archie-tmp-$$
	else
		workdir=$HOME/archie-tmp-$$
	fi
	initrddir=$workdir/mnt/initrd
	archroot=$workdir/mnt/archroot
	
	if [ "$syncpacman" = "yes"  -o ! -d $pacmanlib/archie ]; then
		pacman -Sy
	fi
	
	mkdir -p $workdir/{tmp,arch,archieiso/isolinux}
	mkdir -p $workdir/archieroot/{initrd,root,etc/{archie,rc.d,pam.d,conf.d},dev,proc,sys,bin,sbin,usr,tmp}
	chmod 1777 $workdir/archieroot/tmp
	mkdir -p $initrddir
	mkdir -p $archroot

	splashinfo=""
}

format_target()
{
	echo -e "$C_OTHER$PREFIX_HL ${C_FAIL}Are you sure you want to format and install Arch linux on ${C_H1}$target${C_FAIL} ? [y/N] ${C_CLEAR}\c "
	read key
	if [ -z $key ] || [ ! $key = 'y' -a ! $key = 'Y' ]; then
		rm -r $workdir
		exit
	fi
	printhl "Formatting $target (ext2)..."
	mkfs.ext2 -q -L Archie-$version $target || return 1
}

install_arch()
{
	#printhl "Installing Arch Linux base on $target"
	archpkgs=""
	pacman -Sy -r $archroot
	mkdir -p $archroot/etc/
	# grab base setup/packages.txt, and install to <target>
	#printhl "Downloading Arch linux base package list"
	wget -q ftp://ftp.archlinux.org/current/os/i686/setup/packages.txt -O $workdir/arch/packages.txt || cp /var/cache/pacman/pkg/packages.txt $workdir/arch/packages.txt
	[ $? -ne 0 ] && return 1
	# remove carriage returns which mess everything up
	sed -i s%\\r%%g $workdir/arch/packages.txt
	for pkg in `cat $workdir/arch/packages.txt`; do
		pkgprefix="${pkg%%/*}"
		pkgfile="${pkg##*/}"
		pkgname="${pkgfile%-*-*.pkg.tar.gz}"
		if [ "${pkgprefix}" = "base" ]; then
			for ignorepkg in $ignorepkglist; do
				[ "$ignorepkg" = "$pkgname" ] && break
			done
			[ "$ignorepkg" != "$pkgname" ] && archpkgs="${archpkgs} ${pkgname}"
		fi
	done
	# we must install coreutils 1st...
	pacman_remote $archroot "-d coreutils"
	[ $? -ne 0 ] && return 1
	pacman_remote $archroot "-f $archpkgs"
	[ $? -ne 0 ] && return 1
	# installing /etc/fstab 1st due to new pacman.conf NoUpgrade rules
	install -m 644 $archieconf/etc/fstab $archroot/etc/fstab
	[ ! -f $target ] && echo "$target / ext2 defaults 0 0" >> $archroot/etc/fstab
	mkdir -p $archroot/etc/X11
	cp /etc/pacman.conf $archroot/etc
	cp -r /etc/pacman.d $archroot/etc
	# we need to copy some files due to new pacman.conf NoUpgrade rules...
	#cp /etc/{rc.conf,rc.local} $archroot/etc
	#cp $archieconf/buildarchie/etc/{group,passwd,shadow} $archroot/etc
	# if we dont build archie iso, use current Arch system files:
	#[ ! "$buildarchie" = "yes" ] && cp /etc/{group,passwd,shadow} $archroot/etc
	echo -e "/usr/X11R6/lib\n"\
		"/opt/xfce4/lib\n"\
		"/opt/mozilla/lib/firefox\n"\
		"/opt/kde/lib\n"\
		"/opt/gnome/lib\n"\
		"/opt/qt/lib\n"\
		"/opt/e17/lib\n"\
	       	> $archroot/etc/ld.so.conf
	mknod -m 600 $archroot/dev/initctl p
	mknod $archroot/dev/log c 21 5
	#making sure we'll have bitmaps fonts!
	mkdir -p $archroot/etc/fonts/conf.d/
	ln -sf yes-bitmaps.conf $archroot/etc/fonts/conf.d/10-bitmaps.conf
	#chroot $archroot /usr/bin/fc-cache -f
	return 0
}

verify_archie_packages()
{
	# no need to update pacman on a fresh install
# 	if [ "$installarch" != "yes" ]; then
# 		printhl "Updating pacman packages on target partition ($target)"
# 		pacman_remote $archroot -yu
# 	fi
	#printhl "Verifying Archie package list on target partition ($target)"
	archiepkgs=""
	#wget -q ftp://ftp.archlinux.org/current/os/i686/setup/packages.txt -O $workdir/arch/xfce_packages.txt
	#[ $? -ne 0 ] && fail
	
	# check for and install our gfx driver and deps
	if [ ! -z "$gfx" ]  && [ "$gfx"  != "auto" ] ; then
		livegfxpkgs=""
		for pkg in $gfxpkgs; do
			[ -z "`pacman -Q $pkg -r $archroot 2>/dev/null`" ] && livegfxpkgs="${livegfxpkgs} $pkg"
		done
	fi
	# now add the rest of our pkgs
	for pkg in `awk '{print $1}' /etc/archie/modules/${buildiso}/packages.txt`; do
		# make sure we dont repeat same package name twice...
		#case $archiepkgs in *" "${pkg}" "*) continue; ;; esac
		[ -z "`pacman -Q $pkg -r $archroot 2>/dev/null`" ] && archiepkgs="${archiepkgs} $pkg"
	done
	return 0
}

gfx_auto()
{
	# install the wizard itself
	install -m 755 $archieconf/etc/archie/autogfx $workdir/archieroot/etc/archie/autogfx
	# grab all the pkgs we need
	autogfxpkglist="libgl-dri-archie nvidia-utils-archie nvidia-legacy-utils-archie ati-fglrx-utils-archie"
	for pkg in $autogfxpkglist; do
			[ -z "`pacman -Q $pkg -r $archroot 2>/dev/null`" ] && autogfxpkgs="${autogfxpkgs} $pkg"
	done
	unset autogfxpkglist
}

prepare_archie()
{
	#printhl "Installing Archie packages and scripts in jail (live root)"
	isopkgs="$install2iso"
	# checking for installed packages, and add to "install list" missing packages
	for pkg in $livepkglist; do
		[ -z "`pacman -Q $pkg -r $archroot 2>/dev/null`" ] && isopkgs="${isopkgs} $pkg"
	done

	# check to see if we need to add gensplash pkgs
	if [ "$installsplash" = "yes" ]; then
		for pkg in $gensplashpkglist; do
			[ -z "`pacman -Q $pkg -r $archroot 2>/dev/null`" ] && isopkgs="${isopkgs} $pkg"
		done
	fi

	# we use unionfs to mount 2 dirs (1 ro, 1 rw) into 1 rw dir to emulate the live
	# directory on the iso. just gotta love unionfs :-)
	mount -t unionfs -o dirs=$workdir/archieroot=rw:$archroot=ro none $workdir/archieroot
	[ $? -ne 0 ] && return 1
	# using -f because of stupid nvidia and xorg gl include files conflicts
	pacman_remote $workdir/archieroot "-d -f $isopkgs"
	[ $? -ne 0 ] && return 1

	# only download the next packages (install l8r)
	livepkgs=""
	[ -z "`pacman -Q syslinux 2>/dev/null`" ] && livepkgs="${livepkgs} syslinux"
	[ -z "`pacman -Q busybox 2>/dev/null`" ] && livepkgs="${livepkgs} busybox"
	pacman_remote $workdir/archieroot "-d -w $livepkgs"
	[ $? -ne 0 ] && return 1
	
	# release unionfs mount
	umount $workdir/archieroot
	
	# copying kernel
	vmlinuz=$workdir/archieroot/boot/vmlinuz26beyond
	[ ! -f $vmlinuz ] && vmlinuz=$archroot/boot/vmlinuz26beyond
	cp $vmlinuz $workdir/archieiso/isolinux/vmlinuz
	# FOR MY TESTINGS ONLY!! :
	#cp $archieconf/vmlinuz $workdir/archieiso/isolinux/vmlinuz
	
	# backing-up Arch configuration files to be overwritten with Archie files
	cp $archroot/etc/rc.d/functions $workdir/archieroot/etc/rc.d/functions.arch
	cp $archroot/etc/inittab $workdir/archieroot/etc/inittab.arch
	# installing Archie configs and scripts
	for file in {rc.conf,fstab,modprobe.conf,pam.d/su,archie/xorg.conf.template,rc.d/functions,conf.d/gensplash} ; do 
		install -m 644 $archieconf/etc/$file $workdir/archieroot/etc/$file
	done 
	
	# installing init scripts, using $archieconf/custom when available
	for file in {rc.sysinit,rc.single,rc.multi,rc.local,rc.shutdown,mkxcfg,hd-install} ; do 
		#install -m 755 $archieconf/$file $workdir/archieroot/etc/archie/$file
		if [ -e $archieconf/custom/$file ] ; then 
			install -m 755 $archieconf/custom/$file $workdir/archieroot/etc/archie/$file
		else 
			install -m 755 $archieconf/etc/archie/$file $workdir/archieroot/etc/archie/$file
		fi 
	done 
	
	if [ "$buildiso" ]; then
		# copy private customization files (passwd, themes, etc)
		for file in {group,passwd,shadow,pam.d/su,acpi/events/power}; do
			install -D -m 644 $archieconf/etc/$file $workdir/archieroot/etc/$file
		done
		# check for a custom inittab in the $module
		if [ -e /etc/archie/module/$buildiso/inittab ] ; then
			cp /etc/archie/module/$buildiso/inittab $workdir/archieroot/etc/inittab
		else
			cp  $archieconf/etc/inittab $workdir/archieroot/etc/inittab
		fi
		install -m 440 $archieconf/etc/sudoers $workdir/archieroot/etc/sudoers
		install -m 755 $archieconf/etc/archie/xautostart $workdir/archieroot/etc/archie/xautostart
		# now copy the Archie customization files
		cp -r $archroot/etc/skel/. $workdir/archieroot/root/
		[ -f /etc/archie/modules/$buildiso/.xinitrc ] && cp /etc/archie/modules/$buildiso/.xinitrc $workdir/archieroot/root/.xinitrc
		chown -R root:root $workdir/archieroot/root/
		# create archie home dir and copy files
		[ ! -d $workdir/archieroot/home/archie ] && mkdir -p $workdir/archieroot/home/archie
		cp -r $archroot/etc/skel/. $workdir/archieroot/home/archie/
		cp -r $archroot/etc/skel/. $workdir/archieroot/home/archie/
		[ -f /etc/archie/modules/$buildiso/.xinitrc ] && cp /etc/archie/modules/$buildiso/.xinitrc $workdir/archieroot/home/archie/.xinitrc
		chown -R 1000:100 $workdir/archieroot/home/archie

		# support for autogfx
		[ "$gfx" = "auto" ] && gfx_auto
	else
		# patch current inittab on target partition to match archie startup scripts
		inittab=`cat $archroot/etc/inittab`
		inittab=`echo "$inittab" | sed  -e 's|/etc/rc.sysinit|/etc/archie/rc.sysinit|' \
						-e 's|/etc/rc.single|/etc/archie/rc.single|' \
						-e 's|/etc/rc.multi|/etc/archie/rc.multi|' \
						-e 's|/etc/rc.shutdown|/etc/archie/rc.shutdown|'`
		echo "$inittab" > $workdir/archieroot/etc/inittab
	fi
	# install -m 755 $archieconf/readahead-list $workdir/archieroot/etc/archie/readahead-list
	# install -m 644 $archieconf/readahead-list.txt $workdir/archieroot/etc/archie/readahead-list.txt
	return 0
}

create_initrd()
{
	dd if=/dev/zero of=$workdir/initrd bs=1k count=8192 2> /dev/null
	[ $? -ne 0 ] && return 1
	mke2fs -m 0 -i 1024 -F -q $workdir/initrd
	mount $workdir/initrd $initrddir -o loop || return 1
	pacman_remote $workdir/tmp "-d busybox" >/dev/null 2>&1
	cp -r $workdir/tmp/{usr,sbin,bin} $initrddir
	
	rmdir $initrddir/lost+found
	install -m 755 $archieconf/initrd/linuxrc $initrddir/linuxrc
	install -m 644 $archieconf/initrd/liblinuxrc $initrddir/liblinuxrc
	mkdir -p $initrddir/{dev,sys,lib,mnt/{cdrom,squashimg,liveroot/tmp},proc,etc,var/log,tmp,initrd}
	chmod 1777 $initrddir/tmp
	mknod $initrddir/dev/console c 5 1
	mknod $initrddir/dev/null c 1 3
	mknod $initrddir/dev/ram b 1 1
	mknod $initrddir/dev/systty c 4 0
	mknod $initrddir/dev/tty c 5 0
	mknod $initrddir/dev/tty1 c 4 1
	
	# scsi_mod nls_iso8859-1 <== are built into beyond kernel
	kernel_dir="$workdir/archieroot/lib/modules/*/kernel"
	[ ! -d $workdir/archieroot/lib/modules/ ] && kernel_dir="$archroot/lib/modules/*/kernel"
	cp $kernel_dir/drivers/ide/ide-core.ko $initrddir/initrd/
	cp $kernel_dir/drivers/ide/ide-generic.ko $initrddir/initrd/
	cp $kernel_dir/drivers/ide/ide-disk.ko $initrddir/initrd/
	cp $kernel_dir/drivers/ide/ide-cd.ko $initrddir/initrd/
	cp $kernel_dir/drivers/cdrom/cdrom.ko $initrddir/initrd/
	cp $kernel_dir/drivers/scsi/sd_mod.ko $initrddir/initrd/
	cp $kernel_dir/drivers/scsi/sr_mod.ko $initrddir/initrd/
	cp $kernel_dir/fs/nls/nls_cp437.ko $initrddir/initrd/
	cp $kernel_dir/fs/nls/nls_iso8859-2.ko $initrddir/initrd/
	cp $kernel_dir/lib/zlib_deflate/zlib_deflate.ko $initrddir/initrd/
	cp $kernel_dir/lib/zlib_inflate/zlib_inflate.ko $initrddir/initrd/
	for mod in {squashfs,unionfs,fat,vfat,msdos,ntfs,jbd,ext3,reiserfs,reiser4,jfs,xfs,isofs,udf}; do
		cp $kernel_dir/fs/$mod/$mod.ko $initrddir/initrd/
	done

	if [ "$copyusb" = "yes" ]; then
		for mod in {core/usbcore,storage/usb-storage,host/ohci-hcd,host/uhci-hcd,host/ehci-hcd} ; do
			cp $kernel_dir/drivers/usb/$mod.ko $initrddir/initrd/
		done
	fi
	if [ "$copyfirewire" = "yes" ]; then
		for mod in {sbp2,ohci1394,ieee1394} ; do
			cp $kernel_dir/drivers/ieee1394/$mod.ko $initrddir/initrd/
		done
	fi

	umount $initrddir
	tune2fs -c 0 -i 0 $workdir/initrd >/dev/null 2>&1
	gzip -c -9 $workdir/initrd > $workdir/archieiso/isolinux/initrd.gz
	return $?
}

check_kernel_dir()
{
	kernel_dir="$archroot/lib/modules/*/kernel/$1"
	[ ! -d $archroot/lib/modules/*/kernel/$1 ] && kernel_dir="$workdir/archieroot/lib/modules/*/kernel/$1"
}

create_initramfs()
{
	pacman_remote $workdir/tmp "-d busybox" >/dev/null 2>&1
	mkdir -p $initrddir/{bin,sbin,usr/{bin,sbin}}
	install -m 755 -D $workdir/tmp/bin/busybox $initrddir/bin/busybox
	install -m 755 -D $workdir/tmp/bin/busybox $initrddir/bin/ln
	install -m 755 -D $workdir/tmp/bin/busybox $initrddir/bin/sh
	install -m 755 $archieconf/initrd/linuxrc $initrddir/init
	install -m 644 $archieconf/initrd/liblinuxrc $initrddir/liblinuxrc
	mkdir -p $initrddir/{img,dev,sys,mnt/{cdrom,squashimg,liveroot/tmp},proc,tmp,initrd}
	chmod 1777 $initrddir/tmp
	mknod $initrddir/dev/console c 5 1
	mknod $initrddir/dev/null c 1 3
	mknod $initrddir/dev/ram b 1 1
	mknod $initrddir/dev/systty c 4 0
	mknod $initrddir/dev/tty c 5 0
	mknod $initrddir/dev/tty1 c 4 1

	# scsi_mod nls_iso8859-1 <== are built into beyond kernel
	#kernel_dir="$workdir/archieroot/lib/modules/*/kernel"
	#[ ! -d $workdir/archieroot/lib/modules/ ] && kernel_dir="$archroot/lib/modules/*/kernel"
	# is this better?
	check_kernel_dir "drivers/ide"
	for mod in {ide-core.ko,ide-generic.ko,ide-disk.ko,ide-cd.ko}; do
		cp $kernel_dir/$mod $initrddir/initrd/
	done
	check_kernel_dir "drivers/cdrom"
	cp $kernel_dir/cdrom.ko $initrddir/initrd/
	check_kernel_dir "drivers/scsi"
	cp $kernel_dir/sd_mod.ko $initrddir/initrd/
	cp $kernel_dir/sr_mod.ko $initrddir/initrd/
	check_kernel_dir "fs/nls"
	cp $kernel_dir/nls_cp437.ko $initrddir/initrd/
	cp $kernel_dir/nls_iso8859-2.ko $initrddir/initrd/
	check_kernel_dir "lib/zlib_deflate"
	cp $kernel_dir/zlib_deflate.ko $initrddir/initrd/
	check_kernel_dir "lib/zlib_inflate"
	cp $kernel_dir/zlib_inflate.ko $initrddir/initrd/
	for mod in {squashfs,unionfs,fat,vfat,msdos,ntfs,jbd,ext3,reiserfs,reiser4,jfs,xfs,isofs,udf}; do
		check_kernel_dir "fs/$mod"
		cp $kernel_dir/$mod.ko $initrddir/initrd/
	done

	if [ "$copyusb" = "yes" ]; then
		check_kernel_dir "drivers/usb"
		for mod in {core/usbcore,storage/usb-storage,host/ohci-hcd,host/uhci-hcd,host/ehci-hcd} ; do
			cp $kernel_dir/$mod.ko $initrddir/initrd/
		done
	fi
	if [ "$copyfirewire" = "yes" ]; then
		check_kernel_dir "drivers/ieee1394"
		for mod in {sbp2,ohci1394,ieee1394} ; do
			cp $kernel_dir/$mod.ko $initrddir/initrd/
		done
	fi

	(cd ${initrddir} && find . | cpio --quiet --dereference -o -H newc | gzip -9 >$workdir/archieiso/isolinux/initram.gz)
	return $?
}

add_gensplash()
{
	[ -z "${splashvox}" ] && splashvox="silent"
	splashinfo="video=vesafb:ywrap,mtrr,$splashres-16@60 console=tty1 splash=$splashvox,theme:$splashtheme"
	# not using splash_geninitramfs since we need to make sure theme files are also
	# copied to target Arch system
	#splash_geninitramfs -r $splashres -a $workdir/archieiso/isolinux/initram.gz $splashtheme

	mkdir -p $initrddir/{bin,sbin,usr/{bin,sbin}}
	cp /sbin/splash_helper ${initrddir}/sbin
	cp /sbin/splash_helper $workdir/archieroot/sbin
	mkdir -p ${initrddir}/etc/splash/$splashtheme/images
	mkdir -p $workdir/archieroot/etc/splash/$splashtheme/images
	cp /etc/splash/$splashtheme/$splashres.cfg ${initrddir}/etc/splash/$splashtheme/
	cp /etc/splash/$splashtheme/$splashres.cfg $workdir/archieroot/etc/splash/$splashtheme/


	t="[0-9*]"
	# config file parsing
	pics=`cat "/etc/splash/$splashtheme/$splashres.cfg" | \
	      sed -r -e "/(^(silent)?jpeg=)|(^(silent)?pic${t}*=)/! d" \
	      -e 's/[a-z0-9]+=(.*)/\1/'`
	for pic in $pics ; do
		cp -pRH --parents /etc/splash/$splashtheme/$pic ${initrddir}/
		cp -pRH --parents /etc/splash/$splashtheme/$pic $workdir/archieroot/
	done
	
	icons=`cat "/etc/splash/$splashtheme/$splashres.cfg" | \
	       egrep -v '^#' | grep icon | awk '{print $2}'`
	for icon in ${icons} ; do
		cp -pRH --parents /etc/splash/$splashtheme/$icon ${initrddir}/
		cp -pRH --parents /etc/splash/$splashtheme/$icon $workdir/archieroot/
	done
	
	fonts=`cat "/etc/splash/$splashtheme/$splashres.cfg" | \
	       egrep -v '^#' | grep 'text ' | grep -o '[^ ]\+\.ttf'`
	for font in ${fonts} ; do
		cp -pRH --parents /etc/splash/$splashtheme/$font ${initrddir}/
		cp -pRH --parents /etc/splash/$splashtheme/$font $workdir/archieroot/
	done

	font=`cat "/etc/splash/$splashtheme/$splashres.cfg" | egrep -v '^#' | grep 'text_font='`
	font=${font#*=}
	if [[ -n "${font}" ]]; then
		cp -pRH --parents /etc/splash/$splashtheme/$font ${initrddir}/
		cp -pRH --parents /etc/splash/$splashtheme/$font $workdir/archieroot/
	else
		cp -pRH --parents /etc/splash/luxisri.ttf ${initrddir}/
		cp -pRH --parents /etc/splash/luxisri.ttf $workdir/archieroot/
	fi

	(cd ${initrddir} && find . | cpio --quiet --dereference -o -H newc | gzip -9 >$workdir/archieiso/isolinux/initram.gz)
	return $?
}

add_bootsplash()
{
	splashinfo="splash=silent"
	config=$splashthemesdir/$splashtheme/config/bootsplash-$splashres.cfg
	/sbin/splash -s -f $config >> $workdir/archieiso/isolinux/initram.gz
	return $?
}

create_squashfs_image()
{
	# files and directories to ignore on the squashfs image
	[ -f $archroot/etc/.pwd.lock ] && ignoredirs="etc/.pwd.lock $ignoredirs"
	[ -d $archroot/lost+found ] && ignoredirs="lost+found $ignoredirs"
	ignoredirs="tmp var/log var/mail var/abs var/cache/pacman var/cache/man $ignoredirs"
	# mounting 2 dirs into 1 : archieroot (as read-write) and archroot (as read-only)
	mount -t unionfs -o dirs=$workdir/archieroot=rw:$archroot=ro none $workdir/archieroot 
	[ $? -ne 0 ] && return 1
	# making sure we have updated bindings on archieroot
	ldconfig -r $workdir/archieroot
	# finally making the squashfs image
	mksquashfs $workdir/archieroot/ $workdir/archieiso/archie.sqf -e $ignoredirs > /dev/null
	#mksquashfs $archroot/ $workdir/archieroot/ $workdir/archieiso/archie.sqf -no-duplicates -e $ignoredirs > /dev/null
	[ $? -ne 0 ] && return 1
	umount $workdir/archieroot -t unionfs
}

create_iso()
{
	if [ -z "`pacman -Q syslinux 2>/dev/null`" ]; then
		pacman_remote $workdir/tmp "-d syslinux" #>/dev/null 2>&1
		cp $workdir/tmp/usr/lib/syslinux/isolinux.bin $workdir/archieiso/isolinux/isolinux.bin
	else
		cp /usr/lib/syslinux/isolinux.bin $workdir/archieiso/isolinux/isolinux.bin
	fi
	for file in {archie.c32,splash.txt,splash.cfg,logo.lss} ; do 
		install -m 644 $archieconf/iso/$file $workdir/archieiso/isolinux/$file
	done 
	# writing our simple isoconfig for syslinux
	echo -e "display splash.cfg\n"\
		"F1 splash.txt\n"\
		"F2 splash.cfg\n"\
		"default archie\n"\
		"prompt 1\n"\
		"timeout 20\n"\
		"label menu\n"\
		"  kernel archie.c32\n"\
		"label archie\n"\
		"  kernel vmlinuz\n"\
		"  append initrd=initram.gz quiet $splashinfo\n" \
		>> $workdir/archieiso/isolinux/isolinux.cfg
		#"  append initrd=initram.gz vga=0x317 quiet $splashinfo\n"
	mkisofs -o $isoname -b isolinux/isolinux.bin -c isolinux/boot.cat \
		-no-emul-boot -boot-load-size 4 -boot-info-table -l -R -r -quiet \
		$workdir/archieiso/ > /dev/null
}

status() 
{
	[ "$quiet" != "yes" ] && printhl "$1" || stat_busy "$1"
	shift
	[ "$quiet" != "yes" ] && $* || $* >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		[ "$quiet" != "yes" ] || stat_done
		return 0
	else
		[ "$quiet" != "yes" ] || stat_fail
		fail
		#return 1
	fi
}

###############################################################################
# program begin
###############################################################################

printhl "mkliveiso v$version, by z4ziggy at user-contributions.org\n"

scan_parameters "$@"
check_repositories || exit
check_unionfs || fail
init_archie

if [ "$installarch" = "yes" ]; then
	format_target || fail
	mount $target $archroot $rootparam || fail
	status "Installing Arch Linux base to $target" install_arch
else
	mount $target $archroot $rootparam || fail
fi

if [ "$buildiso" ]; then
	status "Verifying $buildiso package list on target ($target)" verify_archie_packages
	if [ ! -z "$archiepkgs" ]; then
		# install gfx drivers first so that incorrect libgl deps are not dragged in
		[ ! -z "$livegfxpkgs" ] && status "Installing $gfx packages to target ($target)" pacman_remote $archroot "-d $livegfxpkgs"
		[ $? -ne 0 ] && fail
		[ ! -z "$autogfxpkgs" ] && status "Installing $gfx packages to target ($target)" pacman_remote $archroot "-d $autogfxpkgs"
		[ $? -ne 0 ] && fail
		# we ned to add the wizard pkg install here
		status "Installing $buildiso packages to target ($target)" pacman_remote $archroot "$archiepkgs"
		[ $? -ne 0 ] && fail
	fi
fi

[ ! -z "$install2arch" ] && status "Installing selected packages to target ($target)" pacman_remote $archroot "$install2arch"

# making sure fonts are cached properly... maybe this should be done somewhere else?
# do we need fontconfig for this?
chroot $archroot /usr/bin/fc-cache -f
# we can now set $archroot to readonly, just to prevent problems if program breaks...
mount -o remount -r $archroot || fail

status "Installing live CD packages and scripts in jail (live root)" prepare_archie
[ $? -ne 0 ] && fail
[ $installsplash = "yes" ] && status "Installing gensplash theme ($splashtheme) to initram.gz" add_gensplash
status "Creating initial-ramfs (initram.gz)" create_initramfs
#[ $installsplash = "yes" ] && status "Installing bootsplash theme to initrd.gz" add_bootsplash

#status "Creating compressed partition image (squashfs), go have a coffee..." create_squashfs_image
#status "Creating final iso image ($isoname)" create_iso
#cleanup

echo
printhl "Completed successfully."
#printhl "tip: use qemu to test your iso without burning it: qemu -m 512 -boot d -cdrom $isoname"