#!/exec/ash
#
# Make One Linux General Startup Script 5
# Copyright (C) 2005-2007 Keicho Kondo <dgel@users.sourceforge.jp>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

### === 1.Initialization === ###
# Initialize Make One Linux System.

# get variables and functions
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/exec:."
. /exec/libmol

# mount procfs
mkdir -p /proc
mount -t proc proc /proc

# setup DEBUGCMD variable. If debug boot option is present, call debug()
# function several times during script's execution
checkbootparam "debug" && DEBUGCMD="debug" || DEBUGCMD=""

$DEBUGCMD

# trap 1 2 3 15 signals
trap "" 1 2 3 15
# clean console i/o
exec >/dev/console </dev/console 2>&1
# set umask 022
umask 022
# type starting message
echo; echo "${RED}Make ${CYAN}One ${MAGENTA}Linux ${WHITE}Start ${YELLOW}!!${NORMAL}"
# disable kernel messages
echo "0" >/proc/sys/kernel/printk

$DEBUGCMD

### === 2.Setup Storage Devices === ###
# Make storage devices available to mount live data.

echo "${BLUE}Loading Modules for Storage Devices${NORMAL}"
## load all necessary storage kernel modules
load_essential_kernel_modules

## check for scsi
checkbootparam "noscsi" || load_scsi_kernel_modules

## check for raid devices
checkbootparam "noraid" || load_raid_kernel_modules

## check for firewire
checkbootparam "nofirewire" || load_firewire_kernel_modules

## check for additional modules
checkbootparam "addmodules" && load_additional_kernel_modules

## check for misc modules in expert mode
checkbootparam "expert" && load_kernel_modules_from_floppy

## setting dma support on/off
checkbootparam "nodma" && setup_dma "off" || setup_dma "on"

$DEBUGCMD

### === 3.Mount Live Data === ###
#  Mount Live Data on /mnt/iso (Live Data is mostly used as iso filesystem file).
#  If toram/hd option is specified, then mount it on /mnt/copyto as Live Data.
echo "${BLUE}Mounting ${MAGENTA}Live Data${NORMAL}"

# set DEVICES variable
if checkbootparam "from="; then
	DEVICES="$(getbootparam from)"
else
	DEVICES="/dev/hd? /dev/pcd?"
	[ -f "/proc/scsi/scsi" ] && FOUND_SCSI="yes"
	if [ -n "${FOUND_SCSI}" ]; then
		DEVICES="/dev/scd? /dev/scd?? ${DEVICES}"
		checkbootparam "noscsi" || DEVICES="${DEVICES} /dev/sd?[1-9] /dev/sd?[1-9][0-9]"
	fi
	DEVICES="${DEVICES} /dev/ub?[1-9] /dev/ub?[1-9][0-9] /dev/hd?[1-9] /dev/hd?[1-9][0-9]"
fi

mkdir -p ${ISOMOUNT}
# search live data
for d in ${DEVICES}; do
	echo -n "${CRE}${BLUE}Looking for CD/DVD Meida in: ${MAGENTA}${d}${NORMAL}   "
	if pmount "${d}" ${ISOMOUNT} "-o ro" >/dev/null 2>&1; then
		if [ -f "${ISOMOUNT}/boot/${LIVECDSGN}" ]; then
			. ${ISOMOUNT}/boot/${LIVECDSGN}
			echo -n "${CRE} ${GREEN}Accessing Make One Linux Live Data at ${MAGENTA}${d}${GREEN}...${NORMAL}"
			break
		fi
		umount ${ISOMOUNT}
	fi
done; echo

# check whether live data
if [ ! -f "${ISOMOUNT}/boot/${LIVECDSGN}" ]; then
	echo "${CRE}${RED}<< Cannot Mount Live Data!! >>${NORMAL}"
	echo
	startash
fi

$DEBUGCMD

# set toram/tohd system
if checkbootparam "toram" || checkbootparam "tohd"; then
	echo -n "${CRE} ${GREEN}Copying SYSTEM to "

	mkdir -p $COPYTO
	# for toram
	if checkbootparam "toram"; then
		COPYTODEV="tmpfs"
		RAMSIZE="$(getbootparam toram)"
		[ -z "$RAMSIZE" ] && RAMSIZE="700M"
		echo -n "${MAGENTA}ramdisk${GREEN}... Please be patient.${NORMAL}"
		mount -t tmpfs -o size=${RAMSIZE} $COPYTODEV $COPYTO
		[ $? -ne 0 ] && startash "<< Copying failed. ramdisk is not mountable. >>"
		unset RAMSIZE
	# for tohd
	elif checkbootparam "tohd"; then
		COPYTODEV="$(getbootparam tohd)"
		echo -n "${MAGENTA}${COPYTODEV}${GREEN}... Please be patient.${NORMAL}"
		pmount $COPYTODEV $COPYTO "-o rw"
		[ $? -ne 0 ] && startash "<< Copying failed. $(getbootparam tohd) is not mountable. >>"
	fi; echo

	# copying
	cp -a ${ISOMOUNT}/.[^.]* ${COPYTO}/ >/dev/null 2>&1
	cp -a ${ISOMOUNT}/* ${COPYTO}/ >/dev/null 2>&1
	mount -o remount,ro ${COPYTODEV} $COPYTO

	cd_autoeject 1 # autoeject on
	fumount $ISOMOUNT
	DATA="$COPYTO"
	cd_autoeject 0 # autoeject off
fi

$DEBUGCMD

### === 5.Mount Writable Filesystem === ###
# Mount writable filesystem on /memory
echo "${BLUE}Mounting ${MAGENTA}Writable filesystem${NORMAL}"

mkdir -p ${MEMORY}
CHANGESPATH="$(getbootparam changes)"

# for writable device
if [ -d "$CHANGESPATH" ]; then
	if pmount $CHANGESPATH $MEMORY "-o rw"; then
		echo "${CRE} ${GREEN}Created ${YELLOW}/${MEMORY} ${GREEN}on ${MAGENTA}${FOUND_FS} writable device${NORMAL}"
	else
		startash "<< Can't mount $CHANGESPATH. check your changes= boot option. >>"
	fi

# for writable image file
elif [ -f "${DATA}/changes/$CHANGESPATH" ]; then
	if pmount ${DATA}/changes/${CHANGESPATH} $MEMORY "-o loop,rw"; then
		echo "${CRE} ${GREEN}Created ${YELLOW}/${MEMORY} ${GREEN}on ${MAGENTA}${FOUND_FS} writable image file${NORMAL}"
	else
		startash "<< Can't mount $CHANGESPATH. check your changes= boot option. >>"
	fi

# for ramdisk
else
	# memory information
	FOUNDMEM="$(awk '/MemTotal/{print $2}' /proc/meminfo)"
	TOTALMEM="$(awk 'BEGIN{m=0};/MemFree|Cached/{m+=$2};END{print m}' /proc/meminfo)"
	echo "${CRE} ${GREEN}Total memory found: ${YELLOW}${FOUNDMEM} ${GREEN}KB${NORMAL}"

	# calc ram size
	MINSIZE=2000  # Minimum size of additional ram  partitions
	MINLEFT=16000 # At least this much memory minus 30% should remain when home and var are full.
	MAXSIZE="$((${TOTALMEM} - ${MINLEFT}))" # Maximum ramdisk size
	RAMSIZE="$((${TOTALMEM} / 5))"        # Default ramdisk size
	[ -z "${RAMSIZE}" ] && RAMSIZE=100000
	RAMSIZE=$((${RAMSIZE} * 4))

	if [ -z "$TOTALMEM" ]; then
		startash "<< Can't get memory information. >>"
	elif [ "$TOTALMEM" -le "$MINLEFT" ]; then
		echo "${CRE}${RED}<< Your computer does NOT have enough memory size. >>${NORMAL}"
		echo "${CRE}  ${RED}Detected Memory Size : ${TOTALMEM}kb${NORMAL}"
		echo "${CRE}  ${RED}Required Memory Size : ${MINLEFT}kb${NORMAL}"
		startash
	fi

	# create ramdisk
	if mount -t tmpfs -o size=${RAMSIZE}k tmpfs ${MEMORY}; then
		echo "${CRE} ${GREEN}Creating ${YELLOW}/${MEMORY} ${GREEN}(dynamic size=${YELLOW}${RAMSIZE}${GREEN}kb) on ${MAGENTA}shared memory${BLUE}...${NORMAL}"
	else
		startash "<< Can't mount ramdisk. >>"
	fi
fi

$DEBUGCMD

### === Setup Compressed Modules === ###
# Mount Compressed Modules and Unify them
echo "${BLUE}Setting ${MAGENTA}Compressed Modules${NORMAL}"

mkdir -p $CHANGES # save changed files in this dir
mkdir -p $IMAGES # mount compressed modules on this dir
mkdir -p $UNION # CHANGES and IMAGES will be unified and mount them on this dir

# the following dirs are necessary for slax function
mkdir -p var/log
mkdir -p tmp
chmod 1777 tmp

# setup union
if mount -t aufs -o br:${CHANGES}=rw aufs ${UNION} 2>/dev/null; then
	echo "${CRE} ${GREEN}Mounting ${YELLOW}Compressed Modules ${BLUE}and unify to ${YELLOW}aufs${NORMAL}"
	union_insert_modules ${UNION} ${DATA}/mol ${IMAGES} aufs
elif mount -t unionfs -o dirs=${CHANGES}=rw unionfs ${UNION} 2>/dev/null; then
	echo "${CRE} ${GREEN}Mounting ${YELLOW}Compressed Modules ${BLUE}and unify to ${YELLOW}unionfs${NORMAL}"
	union_insert_modules ${UNION} ${DATA}/mol ${IMAGES} unionfs
else
	startash "<< Can't setup union >>"
fi

$DEBUGCMD

### === Setup New Root === ###
# make necessary dirs
mkdir -p ${UNION}/proc
mkdir -p ${UNION}/sys
mkdir -p ${UNION}/dev
mkdir -p ${UNION}/tmp
chmod 1777 ${UNION}/tmp

# make /etc/mtab
mv ${UNION}/etc/mtab ${UNION}/etc/mtab.backup
ln -s /proc/mounts ${UNION}/etc/mtab

# make /etc/fstab
echolog "creating /etc/fstab"
mount -t sysfs none /sys
echo -ne > $UNION/etc/fstab
fstab_update $UNION
umount /sys

# make /fastboot
:>${UNION}/fastboot

# copy /exec
cp -a /exec ${UNION}

# copy replace files
cat /replace/live-replace.list | while read SRC DST; do
	cp -a /replace/$SRC /union$DST
done

$DEBUGCMD

### === Change Root Directory === ###
cd ${UNION} # new root
mkdir -p ${INITRAM} # old root
if [ ! -e dev/console ]; then
	mknod dev/console c 5 1
fi

# change root directory to /union
pivot_root . ${INITRAM}
exec chroot . ${INITRAM}/exec/autosetup-mol "$@" >/dev/console </dev/console 2>&1

