+#!/bin/sh
+# This file is 'sourced' by other scripts, therefore the above line is of no
+# use, except when modifying the file in emacs to have syntax highlighting.
+
+# Constants for return codes
+EXIT_SUCCESS=0
+EXIT_WARNING=1
+EXIT_FAILURE=2
+
+# The starting position for displaying the "X" sign inside the check box [ ]
+CHECK_POSITION=2
+SET_CHECK_POSITION="echo -en \\033[${CHECK_POSITION}G"
+
+# NORMAL prints text in normal color
+NORMAL="echo -en \\033[0;39m"
+# SUCCESS prints text in a green colour
+SUCCESS="echo -en \\033[1;32m"
+# WARNING prints text in a yellow colour
+WARNING="echo -en \\033[1;33m"
+# FAILURE prints text in a red colour
+FAILURE="echo -en \\033[1;31m"
+
+
+# Extracting the version number from a complete package name.
+# Arg. #1: Complete package name with version (ex: gcc-3.4.4 will output 3.4.4)
+get_pkg_ver()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ echo ${1} | sed "s!^.*-\(.*\)!\1!g"
+}
+
+
+# Extracting the base version number from a complete package name.
+# Arg. #1: Complete package name with version (ex: gcc-3.4.4 will output 3.4)
+get_pkg_ver_base()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ echo ${1} | sed "s!^.*-\([0-9]*\.[0-9]*\).*!\1!g"
+}
+
+
+# Extracting the base version number from a complete package name.
+# Arg. #1: Complete package name with version (ex: gcc-3.4.4 will output 3)
+get_pkg_ver_major()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ echo ${1} | sed "s!^.*-\([0-9]*\)\..*!\1!g"
+}
+
+
+# Extracting the name from a complete package name.
+# Arg. #1: Complete package name with version (ex: gcc-3.4.4 will output gcc)
+get_pkg_name()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ echo ${1} | sed "s!^\(.*\)-.*!\1!g"
+}
+
+
+# Saves the content of CFLAGS and CXXFLAGS environment variables.
+save_flags()
+{
+ export OLDCFLAGS=${CFLAGS}
+ export OLDCXXFLAGS=${CXXFLAGS}
+
+ return ${EXIT_SUCCESS}
+}
+
+
+# Saves the content of CFLAGS and CXXFLAGS environment variables, and then
+# set them to empty strings.
+save_flags_no_optimizations()
+{
+ export OLDCFLAGS=${CFLAGS}
+ export OLDCXXFLAGS=${CXXFLAGS}
+ export CFLAGS=""
+ export CXXFLAGS=""
+
+ return ${EXIT_SUCCESS}
+}
+
+
+# Restores the previous values of CFLAGS and CXXFLAGS environment variables. These
+# must have been saved first using save_flags().
+restore_flags()
+{
+ export CFLAGS=${OLDCFLAGS}
+ export CXXFLAGS=${OLDCXXFLAGS}
+
+ return ${EXIT_SUCCESS}
+}
+
+
+# Create log directory and log file for current stage if necessary
+# This should be done automatically...
+init_log_file()
+{
+ mkdir -p ${LFS_LOG_DIR} &&
+ if [ ! -f ${LFS_LOG_FILE} ]; then
+ touch ${LFS_LOG_FILE} || exit 1
+ fi
+}
+
+
+# Create symbolic links for start/stop scripts in /etc/rc.d
+#
+# Arg #1: script name
+# Arg #2: start number
+# Arg #3: stop number
+# Arg #4: level
+static_bootscript_add()
+{
+ local SCRIPTNAME=${1}
+ local START=${2}
+ local STOP=${3}
+ local RCLEVEL=${4}
+
+ local START_LEVELS=""
+ local STOP_LEVELS=""
+
+ if [ "x${RCLEVEL}" = "xS" ]; then
+ START_LEVELS="S"
+ STOP_LEVELS="0 6"
+ elif [ "x${RCLEVEL}" = "x3" ]; then
+ START_LEVELS="3 4 5"
+ STOP_LEVELS="0 1 2 6"
+ else
+ echo "${FUNCNAME}(), invalid level argument : ${*}"
+ return 1
+ fi
+
+ # Making sure bootscript has correct permissions
+ chmod -v 740 /etc/rc.d/init.d/${SCRIPTNAME} &&
+
+ # Removing any old links
+ for level in S 0 1 2 3 4 5 6; do
+ cd /etc/rc.d/rc${level}.d &&
+ rm -v -f $(find . -name "???${SCRIPTNAME}") || exit 1
+ done &&
+
+ if [ ${START} -ne 0 ]; then
+ # Creating new start links
+ for level in ${START_LEVELS}; do
+ cd /etc/rc.d/rc${level}.d &&
+ ln -v -s ../init.d/${SCRIPTNAME} S${START}${SCRIPTNAME} || exit 1
+ done
+ fi &&
+
+ if [ ${STOP} -ne 0 ]; then
+ # Creating new stop links
+ for level in ${STOP_LEVELS}; do
+ cd /etc/rc.d/rc${level}.d &&
+ ln -v -s ../init.d/${SCRIPTNAME} K${STOP}${SCRIPTNAME} || exit 1
+ done
+ fi
+}
+
+
+# Create symbolic links for start/stop scripts in /etc/rc.d
+#
+# Arg #1: level
+# Arg #2: script name
+# Arg #3: start number
+# Arg #4: stop number
+bootscript_add_manual()
+{
+ local RCLEVEL=${1}
+ local SCRIPTNAME=${2}
+ local START=${3}
+ local STOP=${4}
+
+ # Making sure bootscript has correct permissions
+ chmod 740 /etc/rc.d/init.d/${SCRIPTNAME} &&
+
+ # Removing any old links
+ cd /etc/rc.d/rc${RCLEVEL}.d &&
+ rm -v -f $(find . -name "???${SCRIPTNAME}") &&
+
+ if [ ${START} -ne 0 ]; then
+ # Creating new start link
+ cd /etc/rc.d/rc${RCLEVEL}.d &&
+ ln -v -s ../init.d/${SCRIPTNAME} S${START}${SCRIPTNAME} || exit 1
+ fi &&
+
+ if [ ${STOP} -ne 0 ]; then
+ # Creating new stop link
+ cd /etc/rc.d/rc${RCLEVEL}.d &&
+ ln -v -s ../init.d/${SCRIPTNAME} K${STOP}${SCRIPTNAME} || exit 1
+ fi
+}
+
+
+# Create symbolic links for start/stop scripts in /etc/rc.d
+#
+# Arg #1: script name
+# Arg #2: start number
+# Arg #3: stop number
+bootscript_add_rc3()
+{
+ static_bootscript_add ${*} 3
+}
+
+
+# Create symbolic links for start/stop scripts in /etc/rc.d
+#
+# Arg #1: script name
+# Arg #2: start number
+# Arg #3: stop number
+bootscript_add_rcS()
+{
+ static_bootscript_add ${*} S
+}
+
+
+# Add "export" before the variable name
+#
+# Arg #1: variable name
+# Arg #2: filename where the variable is located
+var_export()
+{
+ VARIABLE=${1}
+ FILE=${2}
+
+ # Checking for correct number of arguments
+ if [ $# -ne 2 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ # Checking if file exists
+ if [ ! -f ${FILE} ]; then
+ echo "${FUNCNAME}(), file not found: ${FILE}"
+ return 1
+ fi
+
+ # Checking if variable exists
+ if ! grep "${VARIABLE}=" ${FILE} 1> /dev/null 2>&1; then
+ echo "${FUNCNAME}(), variable not found: ${VARIABLE}"
+ return 1
+ fi
+
+ # Checking if variable is already exported when it is defined
+ if grep "${VARIABLE}=" ${FILE} | grep "export " 1> /dev/null 2>&1; then
+ echo "${FUNCNAME}(), variable already exported in definition: ${VARIABLE}"
+ return 0
+ fi
+
+ # Checking if variable is already exported, in
+ # a "export VARIABLE1 VARIABLE2..." statement
+ if grep "export " ${FILE} | grep " ${VARIABLE}" 1> /dev/null 2>&1; then
+ echo "${FUNCNAME}(), variable already exported in export list: ${VARIABLE}"
+ return 0
+ fi
+
+ sed -i "s!\(^${VARIABLE}=.*\)!export \1!" ${FILE}
+}
+
+
+# Adding a new environment variable to a file.
+#
+# Arg #1: variable name
+# Arg #2: filename where the variable is located
+# Arg #3: new variable value
+# Arg #4: separator string (usually a " " or ":")
+var_add()
+{
+ VARIABLE=${1}
+ FILE=${2}
+ VALUE="${3}"
+ SEP="${4}"
+
+ # Checking for correct number of arguments
+ if [ $# -ne 4 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ # Checking if file exists
+ if [ ! -f ${FILE} ]; then
+ echo "${FUNCNAME}(), file not found: ${FILE}"
+ return 1
+ fi
+
+ # Checking if variable exists
+ if ! grep "${VARIABLE}=" ${FILE} 1> /dev/null 2>&1; then
+ echo "${VARIABLE}=\"${VALUE}\"" >> ${FILE}
+ return $?
+ fi
+
+ # Checking if variable contains the new value
+ if grep "${VARIABLE}=" ${FILE} | grep "${VALUE}" 1> /dev/null 2>&1; then
+ echo "${FUNCNAME}(), variable ${VARIABLE} already contains value: ${VALUE}"
+ return 0
+ fi
+
+ # Adding new value to variable (case where no export before)
+ # We search for the variable name starting at the beginning of the line
+ # For example, this ensures that if the variable name is PATH, then
+ # PATH=... matches but not MANPATH=...
+ if grep "^${VARIABLE}=\"" ${FILE} 1> /dev/null 2>&1; then
+ # Variable value is enclosed by double-quotes
+ sed -i "s!\(^${VARIABLE}=\".*\)\(\"\)!\1${SEP}${VALUE}\"!" ${FILE}
+ else
+ # Variable value is NOT enclosed by double-quotes
+ sed -i "s!\(^${VARIABLE}=.*\)!\1${SEP}${VALUE}!" ${FILE}
+ fi
+ evaluate_retval
+
+ # Adding new value to variable (case with export before)
+ # We search for the variable name starting after an export statement,
+ # at the beginning of a line.
+ # For example, this ensures that if the variable name is PATH, then
+ # PATH=... matches but not MANPATH=...
+ if grep "^export ${VARIABLE}=\"" ${FILE} 1> /dev/null 2>&1; then
+ # Variable value is enclosed by double-quotes
+ sed -i "s!\(^export ${VARIABLE}=\".*\)\(\"\)!\1${SEP}${VALUE}\"!" ${FILE}
+ else
+ # Variable value is NOT enclosed by double-quotes
+ sed -i "s!\(^export ${VARIABLE}=.*\)!\1${SEP}${VALUE}!" ${FILE}
+ fi
+
+ return $?
+}
+
+
+# Adding a new path environment variable to a file.
+#
+# Arg #1: variable name
+# Arg #2: filename where the variable is located
+# Arg #3: new variable value
+var_add_path()
+{
+ var_add ${1} ${2} "${3}" ":" 1>> ${LFS_LOG_FILE} 2>&1
+}
+
+
+# Adding a new string environment variable to a file.
+#
+# Arg #1: variable name
+# Arg #2: filename where the variable is located
+# Arg #3: new variable value
+var_add_str()
+{
+ var_add ${1} ${2} "${3}" " "
+}
+
+
+# Adding a new string to a file.
+#
+# Arg #1: string
+# Arg #2: filename where the variable is located
+string_add()
+{
+ STRING="${1}"
+ FILE=${2}
+
+ # Checking for correct number of arguments
+ if [ $# -ne 2 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ # Checking if file exists
+ if [ ! -f ${FILE} ]; then
+ echo "${FUNCNAME}(), file not found: ${FILE}"
+ return 1
+ fi
+
+ # Checking if string exists
+ if grep "${STRING}" ${FILE} 1> /dev/null 2>&1; then
+ echo "${FUNCNAME}(), string already defined: ${STRING}"
+ return 0
+ fi
+
+ echo "${STRING}" >> ${FILE}
+}
+
+
+# Adding a new environment variable to a shadow password suite file (login.defs)
+#
+# Arg #1: variable name
+# Arg #2: filename where the variable is located
+# Arg #3: new variable value
+var_add_shadow()
+{
+ VARIABLE=${1}
+ FILE=${2}
+ VALUE="${3}"
+
+ # Checking for correct number of arguments
+ if [ $# -ne 3 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ return 1
+ fi
+
+ # Checking if file exists
+ if [ ! -f ${FILE} ]; then
+ echo "${FUNCNAME}(), file not found: ${FILE}"
+ return 1
+ fi
+
+ # Checking if variable contains the new value
+ if egrep "^${VARIABLE}" ${FILE} | grep "${VALUE}" 1> /dev/null 2>&1; then
+ echo "variable ${VARIABLE} already contains value: ${VALUE}"
+ exit 0
+ fi
+
+ # Adding new value to variable
+ # We search for the variable name starting at the beginning of the line
+ # For example, this ensures that if the variable name is PATH, then
+ # PATH... matches but not MANPATH...
+ sed -i "s!\(^${VARIABLE}.*\)!\1:${VALUE}!" ${FILE}
+}
+
+
+# Adding a new group, checking if it already exist before.
+# Arguments: same arguments as for standard groupadd command.
+hv_groupadd()
+{
+ arguments=${*}
+
+ while [ $# -ne 0 ]; do
+ last_argument=${*}
+ shift
+ done
+
+ groupadd ${arguments}
+
+ if [ $? -eq 0 -o $? -eq 9 ]; then
+ # 9 means the group already exists
+ return ${EXIT_SUCCESS}
+ else
+ exit ${EXIT_FAILURE}
+ fi
+}
+
+# Adding a new user, checking if it already exist before
+# Arguments: same arguments as for standard useradd command.
+hv_useradd()
+{
+ arguments="${*}"
+
+ # The last argument is the username
+ while [ $# -ne 0 ]; do
+ last_argument=${*}
+ shift
+ done
+
+ useradd ${arguments}
+
+ if [ $? -eq 0 -o $? -eq 9 ]; then
+ # 9 means the user already exists
+ return ${EXIT_SUCCESS}
+ else
+ exit ${EXIT_FAILURE}
+ fi
+}
+
+
+# Evaluates the return value of the process that was run just before this
+# function was called.
+evaluate_retval()
+{
+ if [ $? -ne 0 ]; then
+ echo "*************"
+ echo "* ERROR *"
+ echo "*************"
+ exit 1
+ fi
+}
+
+# Evaluates the return value of the process that was run just before this
+# function was called.
+eval_retval2()
+{
+ if [ $? -ne 0 ]; then
+ ${SET_CHECK_POSITION}
+ print_status failure
+ echo
+ exit ${EXIT_FAILURE}
+ fi
+}
+
+
+
+
+# Obtain the name of the base directory for the decompressed package.
+# First argument: package name
+static_decompressed_dirname()
+{
+ local PACKAGE=${1}
+
+ local DIRNAME=$(dirname $(tar -tf ${LFS_PKG_DIR}/${PACKAGE}.tar.bz2 | head -n1))
+
+ if [ "x${DIRNAME}" == "x." ]; then
+ DIRNAME=$(basename $(tar -tf ${LFS_PKG_DIR}/${PACKAGE}.tar.bz2 | head -n1))
+ fi
+
+ echo ${DIRNAME}
+}
+
+
+# Applying any patch(es) found for the current package.
+# Will work only if patches have the same base name as
+# the package, followed by a dash:
+# ${1}-*.patch
+#
+# 1st argument: Package name
+# 2: optional target directory.
+apply_patches()
+{
+ PACKAGE=${1}
+ local TARGET_DIR=${PACKAGE}
+
+ # Checking for correct number of arguments
+ if [ $# -gt 2 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ echo "Usage: ${FUNCNAME} PACKAGE-NAME"
+ exit ${EXIT_FAILURE}
+ fi
+
+ if [ $# -eq 2 ]; then
+ TARGET_DIR=${2}
+ else
+ TARGET_DIR=$(static_decompressed_dirname ${PACKAGE})
+ fi
+
+ # Checking if we can find at least one patch.
+ if ls ${LFS_PKG_DIR}/${1}-*.patch 1> /dev/null 2>&1; then
+ cd ${LFS_PKG_DIR}
+ for patch in ${1}-*.patch; do
+ echo "******************************"
+ echo "* Applying patch: ${patch}"
+ echo "******************************"
+ patch -Np1 -d ${LFS_TMP}/${TARGET_DIR} -i ${LFS_PKG_DIR}/${patch} || exit 1
+ done
+ fi
+
+ return $?
+}
+
+
+# Applying patch
+# First argument is the name of the patch
+# Second argument is the package name
+apply_patch()
+{
+ PATCH_FILE=${1}
+ PACKAGE=${2}
+
+ if [ -z "${PATCH_FILE}" ]; then
+ echo
+ echo "apply_patch(): no patch specified."
+ return ${EXIT_FAILURE}
+ fi
+
+ if [ ! -f ${LFS_PKG_DIR}/${PATCH_FILE} ]; then
+ echo
+ echo "${FUNCNAME}(): patch file '${PATCH_FILE}' not found."
+ return ${EXIT_FAILURE}
+ fi
+
+ echo "******************************"
+ echo "* Applying patch: ${PATCH_FILE}"
+ echo "******************************"
+ patch -Np1 -d ${LFS_TMP}/${PACKAGE} -i ${LFS_PKG_DIR}/${PATCH_FILE}
+}
+
+
+# Decompression of a package
+# First argument: package name
+# Second argument: directory where decompressing (optional)
+decompress_package()
+{
+ # Checking for correct number of arguments
+ if [ $# -eq 1 ]; then
+ local TOPDIR=${LFS_TMP}
+ elif [ $# -eq 2 ]; then
+ local TOPDIR=${2}
+ else
+ echo
+ echo "${FUNCNAME}(): Incorrect number of arguments (must be 1 or 2)"
+ return ${EXIT_FAILURE}
+ fi
+
+ local PACKAGE=${1}
+
+ if [ ! -f ${LFS_PKG_DIR}/${PACKAGE}.tar.bz2 ]; then
+ echo "${FUNCNAME}(): Missing source package: \"${PACKAGE}.tar.bz2\""
+ return ${EXIT_FAILURE}
+ fi
+
+ local DECOMPRESSED_DIRNAME=$(static_decompressed_dirname ${PACKAGE})
+
+ if [ -d ${TOPDIR}/${DECOMPRESSED_DIRNAME} ]; then
+ # Removing old source directory (if any)
+ rm -v -rf ${TOPDIR}/${DECOMPRESSED_DIRNAME} || exit 1
+ fi
+
+ # Decompressing package
+ # Option 'U' of tar is to remove each file prior to extracting over it
+ cd ${TOPDIR} &&
+ tar -jxvf ${LFS_PKG_DIR}/${PACKAGE}.tar.bz2 &&
+ cd - 1> /dev/null 2>&1
+}
+
+
+# Installation of a package, removing source and build directories after.
+#
+# First argument: package name
+# Second argument: script name
+# Remaining arguments: additional configure options
+ipkg()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 2 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ static_ipkg ${1} ${2} ${1}
+}
+
+
+# Installation of a package conforming to GNU autotools.
+# The package must be able to be built outside the
+# source directory.
+#
+# First argument: package name
+# Remaining arguments: additional configure options
+ipkg_ac()
+{
+ # Checking for correct number of arguments
+ if [ $# -lt 1 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ local PACKAGE=${1}
+ shift
+ local CONFIGURE_OPTS=${*}
+
+ static_ipkg ${PACKAGE} cis-ac ${PACKAGE} ${CONFIGURE_OPTS}
+}
+
+
+# Installation of a package conforming to GNU autotools,
+# but that must be built inside the source directory.
+#
+# First argument: package name
+# Remaining arguments: additional configure options
+ipkg_ac_nb()
+{
+ # Checking for correct number of arguments
+ if [ $# -lt 1 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ local PACKAGE=${1}
+ shift
+ local CONFIGURE_OPTS=${*}
+
+ static_ipkg ${PACKAGE} cis-ac-nobuild ${PACKAGE} ${CONFIGURE_OPTS}
+}
+
+
+# Installation of a GNOME package.
+#
+# First argument: package name
+ipkg_gnome()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ static_ipkg ${1} cis-gnome ${1}
+}
+
+
+# Installation of a PERL module
+#
+# First argument: package name
+ipkg_pm()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ static_ipkg ${1} cis-pm ${1}
+}
+
+
+# Multiple installation of a package. This is usefull for packages
+# that may need to be installed multiple times, at different
+# times of the build process, like for GCC pas 1 and GCC pass 2.
+#
+# First argument: Real package name
+# Second argument: Installation script name
+# Third argument: Unique identification label in 'install.log'
+ipkg_mult()
+{
+ # Checking for correct number of arguments
+ if [ $# -ne 3 ]; then
+ echo
+ echo "${FUNCNAME}(): Wrong number of arguments"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ static_ipkg ${1} ${2} ${3}
+}
+
+
+# Installation of a package
+#
+# First argument: Real package name
+# Second argument: Installation script name
+# Third argument: Unique identification label in 'install.log'
+# Remaining arguments: Additional configure options
+static_ipkg()
+{
+ local START_TIME=$(echo `date +%s`)
+ local PACKAGE_NAME=${1}
+ local SCRIPT=./${2}
+ local LABEL=${3}
+
+ # Checking for correct number of arguments
+ if [ $# -lt 3 ]; then
+ echo
+ echo "${FUNCNAME}(): Missing argument"
+ echo " command was: \"${FUNCNAME}() $*\""
+ exit ${EXIT_FAILURE}
+ fi
+
+ shift
+ shift
+ shift
+ local CONFIGURE_OPTS=${*}
+
+ # Checking if script is valid and executable
+ if [ ! -x ${SCRIPT} ]; then
+ echo
+ echo "${FUNCNAME}(): script not found: ${SCRIPT}"
+ exit ${EXIT_FAILURE}
+ fi
+
+ PACKAGE_LOG=${LFS_LOG_DIR}/${PACKAGE_NAME}.log
+
+ # Checking if package was previously successfully installed
+ if grep "^${LABEL} successfully installed" ${LFS_LOG_FILE} \
+ 1> /dev/null 2>&1; then
+ return $EXIT_SUCCESS
+ fi
+
+ # Displaying label
+ echo -n "[ ] Installing" ${LABEL}" "
+
+ echo "------------------------" 1>> ${LFS_LOG_FILE}
+ echo "Installing" ${LABEL} 1>> ${LFS_LOG_FILE}
+
+ decompress_package ${PACKAGE_NAME} 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+
+ # Get the name of the decompressed directory
+ local DECOMPRESSED_DIRNAME=$(static_decompressed_dirname ${PACKAGE_NAME})
+
+ # Displaying package source size in log file
+ echo " Source size:" $(du -h -s ${LFS_TMP}/${DECOMPRESSED_DIRNAME} | awk '{ print $1 }') 1>> ${LFS_LOG_FILE}
+
+ # Removing old build directory (if any)
+ if [ -d ${LFS_TMP}/${PACKAGE_NAME}-build ]; then
+ rm -v -rf ${LFS_TMP}/${PACKAGE_NAME}-build 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+ fi
+
+ # Creating build directory
+ mkdir -v ${LFS_TMP}/${PACKAGE_NAME}-build 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+
+ # Executing script.
+ ${SCRIPT} ${PACKAGE_NAME} ${CONFIGURE_OPTS} 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+
+ # Displaying package build size in log file
+ BUILD_SIZE=$(du -h -s -c ${LFS_TMP}/${DECOMPRESSED_DIRNAME} ${LFS_TMP}/${PACKAGE_NAME}-build | grep total | awk '{ print $1 }')
+ echo " Build size : ${BUILD_SIZE}" 1>> ${LFS_LOG_FILE}
+
+ # Some scripts need to preserve the source or build directory. They can
+ # do so by renaming them.
+ if [ -d ${LFS_TMP}/${DECOMPRESSED_DIRNAME} ]; then
+ # Removing source directory
+ rm -v -rf ${LFS_TMP}/${DECOMPRESSED_DIRNAME} 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+ fi
+ if [ -d ${LFS_TMP}/${PACKAGE_NAME}-build ]; then
+ # Removing build directory
+ rm -v -rf ${LFS_TMP}/${PACKAGE_NAME}-build 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+ fi
+
+ # Writing success string to the end of the log file
+ echo "${LABEL} successfully installed" 1>> ${LFS_LOG_FILE}
+
+ # Displaying build time after the package name
+ display_build_time ${START_TIME}
+
+ ${SET_CHECK_POSITION}
+ print_status success
+
+ return $EXIT_SUCCESS
+}
+
+
+# Display the action name, run a command, log its output and display it's
+# status
+# First argument: action name (string)
+# Remaining arguments: command name with it's options
+action_checkbox()
+{
+ # Displaying script name
+ echo -n "[ ]" $1
+ $SET_CHECK_POSITION
+ shift
+ echo $* 1>> ${LFS_LOG_FILE}
+
+ # Executing command
+ $* 1>> ${LFS_LOG_FILE} 2>&1
+ if [ $? -ne 0 ]; then
+ print_status failure
+ echo
+ exit ${EXIT_FAILURE}
+ fi
+
+ print_status success
+
+ return $EXIT_SUCCESS
+}
+
+
+# Display the action name, run a command, log its output and display it's
+# status and the time it took to execute.
+# Note: In case of errors, this function returns an error code instead
+# of exiting.
+# First argument: action name (string)
+# Remaining arguments: command name with it's options
+action_checkbox_time()
+{
+ START_TIME=$(echo `date +%s`)
+
+ # Displaying script name
+ echo -n "[ ]" $1" "
+ shift
+ echo $* 1>> ${LFS_LOG_FILE}
+
+ # Executing command
+ $* 1>> ${LFS_LOG_FILE} 2>&1
+ if [ $? -ne 0 ]; then
+ ${SET_CHECK_POSITION}
+ print_status failure
+
+ return ${EXIT_FAILURE}
+ else
+ # Displaying build time after the package name
+ display_build_time ${START_TIME}
+
+ ${SET_CHECK_POSITION}
+ print_status success
+
+ return $EXIT_SUCCESS
+ fi
+}
+
+
+# Display the action name, run a command, log its output and display it's
+# status. Write to install log file when successfully completed so it
+# won't be called again after a successfull installation.
+# First argument: label (string)
+# Second argument: script name
+run_script_log()
+{
+ LABEL=${1}
+ SCRIPT=${2}
+
+ # Checking for correct number of arguments
+ if [ $# -lt 2 ]; then
+ echo "${FUNCNAME}(): Missing argument"
+ exit ${EXIT_FAILURE}
+ fi
+
+ shift
+ shift
+ SCRIPT_ARGS=${*}
+
+ # Checking if script is valid and executable
+ if [ ! -x ./${SCRIPT} ]; then
+ echo "${FUNCNAME}(): script not found: ${SCRIPT}"
+ exit ${EXIT_FAILURE}
+ fi
+
+ PACKAGE_LOG=${LFS_LOG_DIR}/${LABEL}.log
+
+ # Checking if package was previously successfully installed
+ if grep "^${LABEL} successfully installed" ${LFS_LOG_FILE} 1> /dev/null 2>&1;
+ then
+ return $EXIT_SUCCESS
+ fi
+
+ # Displaying script name
+ echo -n "[ ] ${LABEL}"
+ echo "------------------------" 1>> ${LFS_LOG_FILE}
+ echo "Running " ${LABEL} 1>> ${LFS_LOG_FILE}
+ echo 1>> ${LFS_LOG_FILE}
+
+ # Executing command
+ ./${SCRIPT} ${SCRIPT_ARGS} 1>> ${PACKAGE_LOG} 2>&1
+ eval_retval2
+
+ # Writing success string to the end of the log file
+ echo "${LABEL} successfully installed" 1>> ${LFS_LOG_FILE}
+
+ $SET_CHECK_POSITION
+ print_status success
+
+ return $EXIT_SUCCESS
+}
+
+
+# Display the action name, run a command, log its output and display it's
+# status. Write to install log file when successfully completed so it
+# won't be called again after a successfull installation.
+# First argument: label (string)
+# Second argument: script name
+run_cmd_log()
+{
+ # Checking for correct number of arguments
+ if [ $# -lt 2 ]; then
+ echo "${FUNCNAME}(): Missing argument"
+ exit ${EXIT_FAILURE}
+ fi
+
+ LABEL=${1}
+ shift
+ SCRIPT=${*}
+
+ # Checking if package was previously successfully installed
+ if grep "^${LABEL} successfully installed" ${LFS_LOG_FILE} 1> /dev/null 2>&1;
+ then
+ return $EXIT_SUCCESS
+ fi
+
+ # Displaying script name
+ echo -n "[ ] ${LABEL}"
+ echo "------------------------" 1>> ${LFS_LOG_FILE}
+ echo "${LABEL}" 1>> ${LFS_LOG_FILE}
+ echo 1>> ${LFS_LOG_FILE}
+
+ # Executing command
+ ${SCRIPT} 1>> ${LFS_LOG_FILE} 2>&1
+ eval_retval2
+
+ # Writing success string to the end of the log file
+ echo "${LABEL} successfully installed" 1>> ${LFS_LOG_FILE}
+
+ $SET_CHECK_POSITION
+ print_status success
+
+ return $EXIT_SUCCESS
+}
+
+
+get_total_build_time()
+{
+ INFILE=${1}
+
+ # Checking for correct number of arguments
+ if [ $# -ne 1 ]; then
+ echo "${FUNCNAME}(), wrong number of arguments: ${*}"
+ echo "Usage: ${FUNCNAME} LOGFILE"
+ exit ${EXIT_FAILURE}
+ fi
+
+ TIMES=$(cat ${INFILE} | grep "Build time:" | sed "s!Build time: \(.*\)h!\1!g")
+
+ for time in ${TIMES}; do
+ HOURS=$(( $HOURS + $(echo ${time} | sed "s!^\([0-9]*\)\..*!\1!g") ))
+
+ # The first SED command extracts the minutes (fractions of an hour).
+ # The second SED command removed the leading zero, if applicable.
+ MIN=$(( $MIN + $(echo ${time} | sed "s!.*\.\([0-9][0-9]\)!\1!g" | sed "s!^0\([0-9]\)!\1!g" ) ))
+ done
+
+ HOURS=$(( ${HOURS} + ( ${MIN} / 100 ) ))
+ MIN=$(( ${MIN} % 100 ))
+
+ echo "${HOURS}.${MIN}"
+}
+
+
+display_build_time()
+{
+ END_TIME=$(echo `date +%s`)
+
+ HOURS=$(( ( ${END_TIME} - ${START_TIME} ) / 3600 ))
+ echo -n "("${HOURS}"."
+ echo -n " Build time: ${HOURS}." 1>> ${LFS_LOG_FILE}
+
+ # Time is inferior to 1 hour...
+ MINUTES=$(( ( ( ${END_TIME} - ${START_TIME} ) % 3600 ) / 36 ))
+
+ if [ ${MINUTES} -lt 10 ]; then
+ echo -n "0"
+ echo -n "0" 1>> ${LFS_LOG_FILE}
+ fi
+
+ if [ ${MINUTES} -eq 0 ]; then
+ echo -n "1"
+ echo -n "1" 1>> ${LFS_LOG_FILE}
+ else
+ echo -n ${MINUTES}
+ echo -n ${MINUTES} 1>> ${LFS_LOG_FILE}
+ fi
+
+ echo -n "h)"
+ echo "h" 1>> ${LFS_LOG_FILE}
+}
+
+
+# The print_status prints a coloured "X" letter inside the checkbox to the left
+# of the screen (the checkbox is displayed with the action_checkbox function).
+print_status()
+{
+ if [ $# = 0 ]; then
+ # If no parameters are given to the print_status function, print usage
+ # information.
+ echo "Usage: ${FUNCNAME}() {success|warning|failure}"
+ return ${EXIT_FAILURE}
+ fi
+
+ case "$1" in
+ success)
+ $SUCCESS
+ ;;
+ warning)
+ $WARNING
+ ;;
+ failure)
+ $FAILURE
+ ;;
+ *)
+ echo "Usage: ${FUNCNAME}() {success|warning|failure}"
+ return ${EXIT_FAILURE}
+ ;;
+ esac
+ echo "X"
+ $NORMAL
+}
+
+
+# Testing GCC toolchain
+gcc_toolchain_test_stage1()
+{
+ cd ${LFS_TMP} &&
+ echo 'main(){}' > dummy.c &&
+ cc dummy.c &&
+ readelf -l a.out | grep ': /tools' 1> /dev/null 2>&1
+
+ if [ $? -ne 0 ]; then
+ echo "Testing toolchain failed..."
+ exit 1
+ fi
+
+ rm dummy.c a.out
+}