#!/bin/sh

# Author : Benoit PAPILLAULT <benoit.papillault@free.fr>
# Creation: 21/07/2003

# This script is used to build the ISO root image CD

# read common configuration file

. config
. config-auto

TARGET=work/iso-root

# parameters for spell-binary-install

export BASE="${IMAGE}/install" &&
export INSTALL_ROOT="${TARGET}" &&

# checking image directory
if [ ! -d "${IMAGE}" ]; then
    echo "${IMAGE} is not a directory"
    exit 1
fi

# we need to add src/iso_root to PATH to be able to recursively
# call spell-binary-install

export PATH="${PATH}:src/iso_root"

# function to strip all binaries
strip_binaries() {

  DIR="$1"

  echo "stripping binaries under ${DIR}"

  find "${DIR}" -type f -exec file {} \; |
  grep " ELF " | grep -v "relocatable" |
  cut -d: -f1 |
  while read file;
  do
    strip --strip-debug "${file}"
  done

}

# function to remove static libraries
remove_static_lib() {

    DIR="$1"
    TMP="/tmp/list.$$"

    echo "removing static libraries under ${DIR}"

    find "${DIR}" -type f -exec file {} \; \
        | grep "current ar archive" \
        | awk -F ':' '{print $1}' > "${TMP}"

    (while read file;
     do
       rm "${file}"
     done ) < "${TMP}"

    rm "${TMP}"
}

# usage: spell_versions bash
# returns the grimoire version and the installed version
# you can use it as : 
# grimoire_version=`spell_versions bash | awk '{print $1}'
# installed_version=`spell_versions bash | awk '{print $2}'

spell_versions() {

  local SPELL="$1"
  chroot "${IMAGE}" gaze version "${SPELL}" |
  awk '{print $3" "$4" "$5}' | grep "^${SPELL}" | tail -n 1

}

# usage: grimoire_version bash
# returns the version in the grimoire

grimoire_version() {

  local SPELL="$1"
  spell_versions "${SPELL}" | awk '{print $2}'

}

# usage: installed_version bash
# returns the installed version or "-"

installed_version() {

  local SPELL="$1"
  spell_versions "${SPELL}" | awk '{print $3}'

}

# usage: copy_spell bash
# copy ${BASE}/install/bash_*.tar.bz2 on the /install dir on the ISO
# those tar.bz2 are generated using spell-binary-make and must contain
# all aliens.

copy_spell() {

  local SPELL="$1"

  # we do copy the spell even if it is already installed because some
  # files (doc & man) of installed spells are later removed and thus
  # the installed system can no longer be used for installation

#  local PACKAGE="${TARGET}/var/state/sorcery/packages"
#  if [ -f "${PACKAGE}" ]; then
#    if grep -q "^${SPELL}:" "${TARGET}/var/state/sorcery/packages"; then
#      return 0
#    fi
#  fi

  # use the canonic spell name to search for a tar.bz2
  local C_SPELL=`echo "${SPELL}" | sed s/_/-/g`

  local N_CACHE=`cd "${BASE}" && find . -name "${C_SPELL}_*.tar.bz2" | wc -l`
  if [ "${N_CACHE}" -ne 1 ]; then
    echo "spell ${SPELL} has ${N_CACHE} choice(s). must be one"
    find "${BASE}" -name "${C_SPELL}_*.tar.bz2"
    exit 1
  fi

  local CACHE=`cd "${BASE}" && find . -name "${C_SPELL}_*.tar.bz2" | cut -c3-`

  # stop immediately if the cache has already been copied

  if [ -f "${TARGET}/install/${CACHE}" ]; then
    return 0
  fi

  # copy dependencies

  local tmpdir="/tmp/spell-binary-$$"

  rm -rf "${tmpdir}" && mkdir -p "${tmpdir}" &&
  tar jxf "${BASE}/${CACHE}" -C "${tmpdir}" ./install &&
  grep ".*:.*:on:.*" "${tmpdir}/install/depends" |
  cut -d: -f2 | cut -d'(' -f1 |
  while read dep_spell;
  do
    copy_spell "${dep_spell}" || exit 1
  done &&
  rm -rf "${tmpdir}" || exit 1

  # check once again if the cache has already been copied

  if [ -f "${TARGET}/install/${CACHE}" ]; then
    return 0
  fi

  echo "copying ${CACHE}" &&
  mkdir -p "${TARGET}/install" &&
  cp "${BASE}/${CACHE}" "${TARGET}/install" || exit 1

}

# usage: cat_file file
# output file + file.$ARCH is this latter exist

cat_file()
{

  for file in "$@";
  do
    if [ -f "${file}" ]; then
      cat "${file}"
    fi &&
    if [ -f "${file}.${ARCH}" ]; then
      cat "${file}.${ARCH}"
    fi
  done

}

# umount directories under $TARGET
if [ -d "${TARGET}" ]; then
  DIR=`cd "${TARGET}" && pwd` &&
  cat /proc/mounts | awk '{print $2}' | grep "^${DIR}" | sort -r |
  while read dir;
  do
    echo "umounting ${dir}..."
    umount "${dir}" || exit 1
  done || exit 1
fi

# erase existing directory if any
echo "deleting existing ${TARGET}"
rm -rf "${TARGET}" || exit 1

# create FHS 2.3 directories

cat data/FHS-2.3 | grep -v "^#" | grep -v "^$" | while read dir mode;
do
  mkdir -p "${TARGET}/${dir}" &&
  if [ -n "${mode}" ]; then
    chmod "${mode}" "${TARGET}/${dir}"
  fi
done &&

# for the initrd's pivot_root
mkdir -p "${TARGET}/initrd" &&
# for the smgl.install script
mkdir -p "${TARGET}/mnt/root" &&

# the great big symlink (see http://bugs.sourcemage.org/show_bug.cgi?id=8655)
if [ "${LIB64_SYMLINK}" = "yes" ]; then
  ln -sf lib "${TARGET}/lib64" &&
  ln -sf lib "${TARGET}/usr/lib64"
fi &&

# install spells

# grep -v "^#" : remove comments
# grep -v "^$" : remove blank lines

cat_file src/iso_root/spell-iso-root|
grep -v "^#" | grep -v "^$" | sort -u |
while read spell;
do
  spell-binary-install "${spell}" || exit 1
done || exit 1

# install spell-binary-install
mkdir -p "${TARGET}/usr/bin" &&
# we do not use cp -a since this will create a file owned by an invalid user
cp src/iso_root/spell-binary-install "${TARGET}/usr/bin" &&

# /etc/ld.so.conf
mkdir -p "${TARGET}/etc" &&
for dir in /lib /lib64 /usr/lib /usr/lib64;
do
  if [ -d "${TARGET}/${dir}" ]; then
    echo "${dir}" >> "${TARGET}/etc/ld.so.conf"
  fi
done &&
	
# create correct link under /lib
ldconfig -r "${TARGET}" &&

# /etc/fstab (no need to put devfs since it's mounted by the kernel)
cat > "${TARGET}/etc/fstab" <<EOF
proc    /proc       proc    defaults    0 0
tmpsfs  /dev/shm    tmpfs   defaults    0 0
devpts  /dev/pts    devpts  defaults    0 0
tmpfs   /var/lock   tmpfs   defaults    0 0
tmpfs   /var/log    tmpfs   defaults    0 0
tmpfs   /var/run    tmpfs   defaults    0 0
tmpfs   /var/tmp    tmpfs   defaults    0 0
tmpfs   /tmp        tmpfs   defaults,size=256m,nr_inodes=64m    0 0
EOF

# /etc/mtab -> /proc/mounts
touch "${TARGET}/proc/mounts" &&
ln -sf ../proc/mounts "${TARGET}/etc/mtab" &&

# enable/disable boot scripts

# enable list
for script in %DEV/devices \
  %S/hotplug %S/hostname.sh %S/keymap.sh %S/mountall.sh %S/hwclock.sh \
  %3/network %3/smgl-default-remote-fs %3/smgl-misc;
do
  if [ -f  "${TARGET}/etc/init.d/runlevels/${script}" ]; then
    chmod a+x "${TARGET}/etc/init.d/runlevels/${script}"
  fi
done &&

# disable list
for script in %S/modutils %S/single %S/smgl-sysctl \
  %2/pcmcia %2/smgl-suspend-single %3/mountnetwork;
do
  if [ -f "${TARGET}/etc/init.d/runlevels/${script}" ]; then
    chmod a-x "${TARGET}/etc/init.d/runlevels/${script}"
  fi
done &&

# copy kernel configuration and source
# /etc/sorcery/local/kernel.config -> /boot/config-2.6.8.1
# /var/spool/sorcery/linux-2.6.8.1.tar.bz2{.sign}

mkdir -p "${TARGET}/boot" &&
mkdir -p "${TARGET}/var/spool/sorcery" &&
mkdir -p "${TARGET}/etc/sorcery/local" &&

chroot "${IMAGE}" gaze sources linux > /tmp/linuxsources.list
for LINUX_SOURCES in $( cat /tmp/linuxsources.list )
do
cp -a "${IMAGE}/var/spool/sorcery/${LINUX_SOURCES}" \
        "${TARGET}/var/spool/sorcery" || exit 1

done &&
rm /tmp/linuxsources.list &&

# /etc/modules and /etc/modules.conf

mkdir -p "${TARGET}/etc" &&
touch "${TARGET}/etc/modules" &&
touch "${TARGET}/etc/modules.conf" &&
touch "${TARGET}/etc/modprobe.conf" &&

if [ "${ARCH}" = "ppc" ]; then
  echo "therm_adt746x" >> "${TARGET}/etc/modules"
fi

# copy the dialog configuration
cp "${IMAGE}/etc/sorcery/dialogrc" "${TARGET}/etc/dialogrc"

# copy some files from our sources
cp src/iso_root/inittab       "${TARGET}/etc/inittab" &&
cp src/iso_root/smgl.install  "${TARGET}/usr/sbin" &&
cp src/iso_root/mkinitrd-smgl "${TARGET}/usr/sbin" &&
cp src/iso_root/MAKEDEV       "${TARGET}/sbin/MAKEDEV" &&

mkdir -p "${TARGET}/etc" &&
for file in \
	src/image/passwd \
	src/image/shadow \
	src/image/group \
	base-files/nsswitch.conf \
	base-files/protocols \
	base-files/services \
	base-files/rpc \
;
do
  cp "${file}" "${TARGET}/etc"
done

# remove unneeded spells (it needs sorcery & grimoire installed)

cat_file src/iso_root/spell-iso-root.rm|
grep -v "^#" | grep -v "^$" |
while read spell;
do
  spell-binary-uninstall "${spell}" || exit 1
done || exit 1

# needed by the /etc/init.d/hostname.sh script

HOSTNAME="smgl-install"
echo "${HOSTNAME}"            > "${TARGET}/etc/hostname" &&
echo "127.0.0.1 ${HOSTNAME}" >> "${TARGET}/etc/hosts" &&

cat > "${TARGET}/etc/issue" <<EOF
Welcome to Source Mage GNU/\s ${ISO_VERSION_MAJOR}-${ISO_VERSION_MINOR} \l
Linux kernel \r on an \m
EOF

# create devices from a tar.gz
# cat src/initrd/dev.tar.gz | (cd "${TARGET}"; tar zxf -)

# remove un-needed files (doc & include)
# they might be needed by spell-binary-install however

rm -rf "${TARGET}"/lib/modules/*.old &&
rm -rf "${TARGET}"/usr/doc &&
rm -rf "${TARGET}"/usr/info &&
rm -rf "${TARGET}"/usr/man &&
rm -rf "${TARGET}"/usr/share/aclocal &&
rm -rf "${TARGET}"/usr/share/autoconf &&
rm -rf "${TARGET}"/usr/share/doc &&
rm -rf "${TARGET}"/usr/share/emacs &&
rm -rf "${TARGET}"/usr/share/gettext &&
rm -rf "${TARGET}"/usr/share/gnome &&
rm -rf "${TARGET}"/usr/share/i18n &&
rm -rf "${TARGET}"/usr/share/info &&
rm -rf "${TARGET}"/usr/share/man &&
find "${TARGET}/usr/share/terminfo" -mindepth 1 -maxdepth 1 \
  -path "${TARGET}/usr/share/terminfo/l" -prune -o -exec rm -rf {} \; &&
find "${TARGET}/usr/share/terminfo/l" -mindepth 1 -maxdepth 1 \
  -path "${TARGET}/usr/share/terminfo/l/linux" -prune -o -exec rm -rf {} \; &&
rm -rf "${TARGET}"/usr/include &&
rm -f "${TARGET}"/usr/lib/*.o &&
rm -rf "${TARGET}"/usr/local &&
rm -rf "${TARGET}"/usr/jed/doc &&
rm -rf "${TARGET}"/usr/jed/info &&
rm -rf "${TARGET}"/var/lock &&
rm -rf "${TARGET}"/var/log &&
rm -rf "${TARGET}/var/run" &&
rm -rf "${TARGET}"/usr/lib/perl5 &&

# /usr/lib/locale/ used by /usr/bin/locale
# as well as /usr/lib/locale/locale-archive & /usr/share/locale/locale.alias

# /usr/share/aclocal [parted] 
# /usr/share/consolefonts [console-data] used by consolechars
# /usr/share/consoletrans [console-data] 
# /usr/share/et [e2fsprogs]
# /usr/share/i18n [glibc]
# /usr/share/keymaps [console-data]
# /usr/share/locale is used by smgl.install
# /usr/share/misc [util-linux]
# /usr/share/ss [e2fsprogs]
# /usr/share/tabset [ncurses]
# /usr/share/terminfo
# /usr/share/unidata
# /usr/share/videomodes
# /usr/share/zoneinfo

# create some directories (/tmp, /var/run, /var/lock, /initrd)

mkdir -p "${TARGET}/var/lock" &&
mkdir -p "${TARGET}/var/log" &&
mkdir -p "${TARGET}/var/run" &&
mkdir -p "${TARGET}/initrd" || exit 1

# create /etc/sourcemage_version used by initrd to recognize the CD as
# a Source Mage GNU/Linux CD

mkdir -p "${TARGET}/etc" &&
cat > "${TARGET}/etc/sourcemage_version" <<EOF
Source Mage GNU/Linux ${ISO_VERSION_MAJOR}-${ISO_VERSION_MINOR} ${ARCH}
EOF

cp src/iso_root/boot.bmp "${TARGET}/boot" &&

# create /etc/installerdata
mkdir -p "${TARGET}/etc/installerdata" &&
echo "VERSION=`date +%Y%m%d`" > "${TARGET}/etc/installerdata/version" &&
for file in fstab \
            install.guide \
            kernel.help \
            raidlevel;
do
  cp "src/iso_root/installerdata/${file}" "${TARGET}/etc/installerdata"
done &&
cat_file src/iso_root/installerdata/install-list > \
  "${TARGET}/etc/installerdata/install-list" &&
cat_file src/iso_root/installerdata/optional-list > \
  "${TARGET}/etc/installerdata/optional-list" &&
cp data/FHS-2.3 "${TARGET}/etc/installerdata/FHS-2.3" &&

# copy stable sorcery
mkdir -p "${TARGET}/install" &&
cp sorcery-stable.tar.bz2 "${TARGET}/install" &&

# copy stable grimoire
mkdir -p "${TARGET}/install" &&
cp stable.tar.bz2 "${TARGET}/install" &&

# copy spells in /install

(cat_file src/iso_root/installerdata/install-list &&
 cat_file src/iso_root/installerdata/optional-list)|
grep -v "^#" | grep -v "^$" | sort -u |
while read SPELL;
do
  copy_spell "${SPELL}" || exit 1
done || exit 1

# remove static libraries
find "${TARGET}" -name \*.a -exec rm {} \;
find "${TARGET}" -name \*.la -exec rm {} \;
#strip_binaries "${TARGET}"

case "${ISOROOT_FS}" in
  none) ;;
  squashfs) mksquashfs "${TARGET}" "${TARGET}.fs" -noappend ;;
  *) echo "${ISOROOT_FS} is not supported for ISOROOT_FS"; exit 1;;
esac

