#!/bin/bash
#
# LIBMOLMAKE -- Function library for molmake
# Copyright (C) 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
#

# ============================
# Variables
# ============================

# Sign for probing live system. don't edit it.
LIVECDSGN="livecd.sgn"

# set color
RESET="]R"       # Reset fb color mode
CRE="
[K"       # Erase to end of line
CLEAR="c"        # Clear and reset Screen
NORMAL="[0;39m"  # Normal Color
RED="[1;31m"     # Failure or error message
GREEN="[1;32m"   # Success message
YELLOW="[1;33m"  # Descriptions
BLUE="[1;34m"    # System message
MAGENTA="[1;35m" # Found devices or drivers
CYAN="[1;36m"    # Questions
WHITE="[1;37m"   # Hint


# ============================
# Tool functions
# ============================

# Check variable
# $1 = variable name
# $2 = variable
#
check_variable()
{
	[ -z "$2" ] && die "<< $1 variable is not filled. Check your configuration. >>"
}

# Allow only root account
#
check_user_account()
{
	#[ "$(id -un)" != "root" ] && die "<< Please login by root account! >>"
	[ "$UID" -ne 0 ] && die "<< Please login by root account! >>"
}

# Load MOL config files
# $1 = config files root directory
#
load_molmake_config()
{
	[ -f "${1}/molmake.conf" ] || die "<< Can't find molmake.conf. >>"
	. ${1}/molmake.conf
	if [ -d "${1}/molmake.conf.d" ]; then
		for conf in ${1}/molmake.conf.d/*; do
			. $conf
		done
	fi
}

# Exec commands with verbose output
# $1 = sum; 0=none, 1=log, 2=outputline, 4=quiet
#
cmd()
{
	local NUM=$1; shift

	[ "$(($NUM - 2))" -ge 0 ] && { local LINE="on"; NUM=$(($NUM - 2)); }
	[ "$(($NUM - 1))" -ge 0 ] && { local LOG="on"; NUM=$(($NUM - 1)); }

	[ -n "$LOG" ] && echo $* >>${BUILD_ROOT}/log
	[ -n "$LINE" ] && echo $*
	#[ -n "$QUIET" ] && $* >/dev/null 2>&1 || $*
	$*
}


# Make list
# output 1 line list
# $@ = list files
#
make_list()
{
	find $@ -name "*.list" | xargs cat | while read LINE; do
		case $LINE in \#*) continue ;; esac # continue comment line
		[ "$LINE" == "" ] && continue # continue empty line
		echo -n "$LINE "
	done
	if [ 0$? -ne 0 ]; then return 1; fi
}

# Error messages
# output error messages and quit
# $1 = message
#
die()
{
	echo "$1" >/dev/stderr 2>&1
	exit 1
}


# ============================
# Initramfs functions
# ============================

# Get dynamic link library list
# $1 = dynamic linked command
#
get_library_list()
{
	LD="/lib/ld-linux.so.2" # set linker
	for lib in $($LD --list $1 | awk '{print $(NF-1)}'); do
		if [ "$lib" == "dynamic" -o "$lib" == "=>" ]; then
			continue
		elif [ -L "$lib" ]; then
			readlink -f $lib
			echo $lib
		elif [ -f "$lib" ]; then
			echo $lib
		fi
	done
}

# Get busybox applets list
# $1 = busybox command
# 
get_busybox_applet_list()
{
	local FLAG=
	local IFS=","
	[ ! -x "$1" ] && return 1
	$1 | while read LINE; do
		if [ "$FLAG" == "on" ]; then
			for f in $LINE; do
				echo -n $f | sed -e 's/\t/\ /g'
			done
		fi
		[ "$LINE" != "Currently defined functions:" ] || FLAG="on"
	done
	if [ 0$? -ne 0 ]; then die "<< Can't get busybox applets list >>"; fi
}

# Make device special files
# $1 = root directory for device files.
# $@ = device list
#
make_device_files()
{
	DEVICE_ROOT="$1"; shift
	find $@ | xargs grep -v "^#" | while read TYPE MODE USERID GROUPID MAJOR MINOR START END NAME ZERO; do
		# if device type is link, then MODE is destination and USERID is source.
		if [ "$TYPE" == "l" ]; then
			ln -s ${USERID} ${DEVICE_ROOT}/${MODE}
			continue
		# if device type is directory, then MAJOR is directory name.
		elif [ "$TYPE" == "d" ]; then
			mkdir -m $MODE -p ${DEVICE_ROOT}/${MAJOR}
			chown $USERID:$GROUPID ${DEVICE_ROOT}/${MAJOR}
			continue
		# if device type is block or char, then specified devices will be created.
		elif [ "$TYPE" == "b" -o "$TYPE" == "c" ]; then
			if [ "$START" -gt "$END" -o "$START" -lt "1" ]; then
				die "<< $0: Invaild argument >>"
			elif [ "$START" -eq "$END" ]; then
				mknod -m $MODE ${DEVICE_ROOT}/${NAME} $TYPE $MAJOR $MINOR
				chown $USERID:$GROUPID ${DEVICE_ROOT}/${NAME}
			else
				for (( NUM=$START ; NUM<=$END ; NUM++ )); do
					if [ -z "$ZERO" -a "$START" -eq "$NUM" ]; then
						mknod -m $MODE ${DEVICE_ROOT}/${NAME} $TYPE $MAJOR $(($MINOR + $NUM - 1))
						chown $USERID:$GROUPID ${DEVICE_ROOT}/${NAME}
					else
						mknod -m $MODE ${DEVICE_ROOT}/${NAME}$(($NUM - 1)) $TYPE $MAJOR $(($MINOR + $NUM - 1))
						chown $USERID:$GROUPID ${DEVICE_ROOT}/${NAME}$(($NUM - 1))
					fi
				done
			fi
			continue
		fi
	done
	if [ 0$? -ne 0 ]; then die "<< Can't make device files correctly >>"; fi
}

# Make initramfs image
# $1 = initramfs root directory
# $2 = file path
#
make_initramfs()
{
	( cd $1; find . | cpio -o -H newc | gzip --best >$2 )
	if [ "$?" -ne 0 ]; then die "<< Can't make initramfs image >>"; fi
}


# ============================
# Module functions
# ============================

# Create module
# call mksquashfs with apropriate arguments
# $1 = directory which will be compressed to squashfs module
# $2 = output .mo file
# $3 = optional (cf. -keep-as-directory argument, -e files...)
#
make_squashfs_module()
{
	mksquashfs "$1" "$2" $3 >/dev/null
	if [ 0$? -ne 0 ]; then return 1; fi
	chmod oga-x "$2" # remove execute attrib
}

# call create_compressed_fs with apropriate arguments
# $1 = directory which will be compressed to squashfs module
# $2 = output .mo file
# $3 = optional (cf. -x file1 -x file2...)
#
make_cloop_module()
{
	mkisofs -r "$1" $3 | create_compressed_fs - 65536 >"$2"
	if [ 0$? -ne 0 ]; then return 1; fi
	chmod oga-x "$2" # remove execute attrib
}

# interface for making module
# $1 = filesystem name (squashfs or cloop)
# $2 = directory which will be compressed to module
# $3 = output .mo file
# $* = exclude files
#
make_module()
{
	MODULE_FS="$1" ROOTDIR="$2" OUTPUT="$3"; shift; shift; shift
	if [ "$MODULE_FS" == "squashfs" ]; then
		if [ -z "$*" ]; then
			make_squashfs_module ${ROOTDIR} ${OUTPUT}
		else
			make_squashfs_module ${ROOTDIR} ${OUTPUT} "-e $*"
		fi
	elif [ "$MODULE_FS" == "cloop" ]; then
		if [ -z "$*" ]; then
			make_cloop_module ${ROOTDIR} ${OUTPUT}
		else
			make_cloop_module ${ROOTDIR} ${OUTPUT} "-x $(echo $* | sed -e 's/\ /\ -x\ /g')"
		fi
	else
		die "<< $MODULE_FS is not supported filesystem >>"
	fi
}

# Create module root directory
# $1 = directory which will be compressed to module
# $2 = include list for this module
#
make_module_rootdir()
{
	local INCLUDE=
	mkdir -p $1
	for INCLUDE in $(cat $2); do
		cp -a --parents "$INCLUDE" $1
	done
}


# ============================
# ISO functions
# ============================

# Copy install2win (harddisk installer)
# $1 = source directory
# $2 = destination directory
#
copy_install2win()
{
	mkdir -p ${2}/boot/grub
	install -m 644 ${1}/stage[12]       ${2}/boot/grub/
	install -m 755 ${1}/flushdrv.exe    ${2}/boot/grub/
	install -m 755 ${1}/msgbox.exe      ${2}/boot/grub/
	install -m 755 ${1}/grubinstall.exe ${2}/boot/grub/
	install -m 755 ${1}/setup.bat       ${2}/boot/grub/
	install -m 755 ${1}/unsetup.bat     ${2}/boot/grub/
	install -m 755 ${1}/mkmenu.bat      ${2}/boot/grub/
	install -m 755 ${1}/install2win.bat ${2}/
}

# Copy install2lin (harddisk installer)
# $1 = source directory
# $2 = destination directory
#
copy_install2lin()
{
	mkdir -p ${2}/boot/grub
	install -m 755 ${1}/setup.sh       ${2}/boot/grub/
	install -m 755 ${1}/unsetup.sh     ${2}/boot/grub/
	install -m 755 ${1}/install2lin.sh ${2}/
}

