#!/bin/sh
# Author: Didier Spaier, Paris, France
#
# Before running this script, adapt MIRROR and PATHTOISO below to your
# installation.
#
# This script build a Slint ISO
#
CWD=$(pwd)
SLACKVERSION="14.2"
SLINTVERSION="14.2"
TAG=""
TAGVERSION=${SLINTVERSION}$TAG
KERNEL_VERSION=4.4.38

usage() {
  printf %b "Usage: $0 32|64 0|1\n       0|1: without|with background image\n"
  exit
}
if [ $# -ne 2 ]; then usage; fi
if [ $1 -ne 32 ] && [ $1 -ne 64 ]; then usage; fi
if [ $2 -ne 0 ] && [ $2 -ne 1 ]; then usage; fi
SFX=$1
sfx=$(echo $SFX|grep 64)
PATHTOISO=/storage/images_iso/slint${sfx}-${TAGVERSION}.iso
SLINTREPO=../../slint
MIRROR=/storage/slackware${sfx}-$SLACKVERSION
SCRIPTS=../localization/scripts
DATESTAMP=`date -u +%Y%m%d`
if [ ! $UID -eq 0 ]; then
  printf "%b"  "Please execute this script as root.\n"
  exit
fi
TMP=$(mktemp -d) || exit 1
ISO=/tmp/iso$sfx
. $SCRIPTS/SeTlocales
if [ ! -f $ISO/slint/DONOTREMOVEME.TXT ]; then
  echo "The file /tmp/iso/slint/DONOTREMOVEME.TXT is missing,"
  echo "thus I can't check that the package tree fits the target system."
  exit
fi
if ! grep "Slint version: ${SLINTVERSION}" $ISO/slint/DONOTREMOVEME.TXT 1>/dev/null; then
  echo "Mismatch between the versions of the package tree and target system"
  exit
fi
if ! grep "System: ${SFX}" $ISO/slint/DONOTREMOVEME.TXT 1>/dev/null; then
 echo "Mismatch (32-bit vs 64-bit) between the package tree and the target system."
 exit
fi
# Put some docs at the root of the tree
sed "s/<date>/$DATESTAMP/;s/+version+/slint${sfx}-${TAGVERSION}.iso/" docs/CONTENT.TXT > $ISO/CONTENT.TXT
sed "s/+version+/$TAGVERSION/g" docs/README.TXT > $ISO/README.TXT
sed "s/+version+/$TAGVERSION/g" docs/Slint-HOWTO > $ISO/Slint-HOWTO
echo $DATESTAMP > $ISO/DateBuilt
# Copy to $ISO/{EFI,isolinux,kernels} all files needed but the initrd 
rm -rf $ISO/{EFI,isolinux,kernels}
mkdir -p $ISO/isolinux
cp -r $MIRROR/kernels $ISO
cp $CWD/source/slackware$sfx-$KERNEL_VERSION/isolinux/initrd.img $ISO/isolinux
if [ "$SFX" = "64" ]; then
  mkdir -p $ISO/EFI/BOOT
  cp source/EFI/BOOT/elilo-3.16-x86_64.efi $ISO/EFI/BOOT/BOOTx64.EFI
  cp source/EFI/BOOT/{help.msg,elilo.conf} $ISO/EFI/BOOT
  cp source/EFI/BOOT/message${SFX} $ISO/EFI/BOOT/message.msg
  cp source/slackware$sfx-$KERNEL_VERSION/kernels/huge.s/bzImage $ISO/EFI/BOOT/vmlinuz
  cp source/slackware$sfx-$KERNEL_VERSION/kernels/huge.s/bzImage $ISO/isolinux/linux
else
  cp source/slackware$sfx-$KERNEL_VERSION/kernels/hugesmp.s/bzImage $ISO/isolinux/linux
fi
cp source/isolinux/{f1.txt,paysage.png,isolinux.bin,BEEP} $ISO/isolinux
cp source/EFI/BOOT/message${SFX} $ISO/isolinux/message.txt
cp source/isolinux/vesamenu.c32 $ISO/isolinux
if [ $2 -eq 0 ]; then
  iconv -f UTF-8 -t CP437 -o $ISO/isolinux/isolinux.cfg source/isolinux/isolinux-vesamenu.cfg.${SFX}
else
  iconv -f UTF-8 -t CP437 -o $ISO/isolinux/isolinux.cfg source/isolinux/isolinux-landscape.cfg.${SFX}
fi
# Third step: prepare and put in $TMP stuff needed for internationalization
# =========================================================================
#
printf "%b" "\nPreparation in progress..."
mkdir $TMP/initrd
( cd $TMP/initrd
  gunzip -cd $ISO/isolinux/initrd.img | \
  cpio -i -d -m -H newc --no-absolute-filenames \
)
installpkg --root $TMP/initrd $SLINTREPO/installer/brltty.installer*.t?z 1>/dev/null
installpkg --root $TMP/initrd $SLINTREPO/installer/installer-translations*.t?z 1>/dev/null
installpkg --root $TMP/initrd $(find $ISO -name spkg*.t?z) 1>/dev/null
( cd $TMP/initrd/sbin
	patch -p0 < $CWD/patches/probe_nvme.diff
)
mkdir -p $TMP/initrd/usr/share/fonts
cp fonts/* $TMP/initrd/usr/share/fonts
# Copying new and modified files in $ISO/isolinux/

# We'll include a font (encoded in CP437), as if no font is set, text files are
# displayed using native font (confirmed by Gene Cumm on syslinux mailing list),
# but native (or hardware) code page can differ upon country, according to:
# http://www.drdos.net/documentation/usergeng/17ugch17.htm
cp -p source/isolinux/ter-i16b.psf $ISO/isolinux
# Copying new and modified files in $TMP/initrd/
for i in $(<$CWD/source/scripts); do
  mkdir -p $TMP/initrd/$(dirname $i)
  cp -p $SCRIPTS/$(basename $i) $TMP/initrd/$(dirname $i)
  chmod 0755 $TMP/initrd/$(dirname $i)/$(basename $i)
done
# Remove INSURL as we don't provide installation through http/ftp, that
# would need a remote packages tree like on the ISO including the
# unmodified Slackware packages. Users can still provide such a tree
# copied from an ISO and export it through NFS or Samba.
rm $TMP/initrd/usr/lib/setup/INSURL
# Put in the initrd files (mostly programs and shared libaries) that we need
# in addition to those already included in the genuine Slackware initrd
( cd $TMP
tar xf $MIRROR/slackware$sfx/a/gettext-*.t?z
# We need these programs to display translations
cp -a usr/bin/{envsubst,gettext*}  initrd/usr/bin
# To use spkg, we need xzdec shipped in the xz package
tar xf $MIRROR/slackware$sfx/a/xz-*.t?z
cp usr/bin/xzdec initrd/bin
# In addition to the program dialog, we'll need its translation files for
# included languages
tar xf $MIRROR/slackware$sfx/a/dialog-*.t?z
# we'll need the translation files associated to programs like cfdisk for
# included languages
tar xf $MIRROR/slackware$sfx/a/util-linux-*.t?z
# we will include gconv-modules and all libraries in /usr/lib{$sfx}/gconv
# associated to encodings of PO files
mkdir -p initrd/usr/lib$sfx/gconv glibc-solibs
tar xf $MIRROR/slackware$sfx/a/glibc-solibs-*.t?z
for i in gconv-modules ISO8859-1.so ISO8859-15.so ISO8859-2.so KOI8-R.so; do
  cp -a usr/lib$sfx/gconv/$i initrd/usr/lib$sfx/gconv
done
tar xf $MIRROR/slackware$sfx/l/glibc-i18n-*.t?z
# Let's ship nano, a newbie friendly text editor, and its dependency
# libmagic.
tar xf $MIRROR/slackware$sfx/a/file-*t?z
tar xf $MIRROR/slackware$sfx/ap/nano-*t?z
cp usr/lib$sfx/libmagic.so.1.0.0 initrd/usr/lib$sfx
cp usr/bin/nano initrd/bin
# Copying /usr/lib$sfx/locale/<locale>/* and the (generated) MO files in: $TMP/initrd
mkdir -p initrd/usr/lib$sfx/locale
for Locale in $(<$CWD/source/locales_list_sorted_by_name); do
  ll_TT=$(echo $Locale|cut -c 1-5)
  ll=$(echo $Locale|cut -c 1-2)
  SeTCode
  SeTLocaleDir
# Let's include the files gettext needs in /usr/lib$sfx/locale to work.
# I could have included (generated) locale_archive instead to save
# some space on the initrd, but this would have prevented the user to
# run this script on a machine with a different ARCH than the target.
# Just in case I change my mind (PS. I did :-)
# We'll also include translation files for programs used during installation
# coming from packages unpacked above
# We'll compile the locale definitions taken from the host system.
#localedef --add-to-archive /usr/lib$sfx/locale/${ll_TT} \
#  --prefix=$TMP/initrd 1>/dev/null
  mkdir -p initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  cp -r  usr/lib$sfx/locale/$Locale \
    initrd/usr/lib$sfx/locale
  if [ -f  usr/share/locale/$LocaleDir/LC_MESSAGES/gettext-runtime.mo ]; then
    cp usr/share/locale/$LocaleDir/LC_MESSAGES/gettext-runtime.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  elif [ -f usr/share/locale/$ll/LC_MESSAGES/gettext-runtime.mo ]; then
    cp usr/share/locale/$ll/LC_MESSAGES/gettext-runtime.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  fi
  if [ -f  usr/share/locale/$LocaleDir/LC_MESSAGES/dialog.mo ]; then
    cp usr/share/locale/$LocaleDir/LC_MESSAGES/dialog.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  elif [ -f usr/share/locale/$ll/LC_MESSAGES/dialog.mo ]; then
    cp usr/share/locale/$ll/LC_MESSAGES/dialog.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  fi
  if [ -f  usr/share/locale/$LocaleDir/LC_MESSAGES/util-linux.mo ]; then
    cp usr/share/locale/$LocaleDir/LC_MESSAGES/util-linux.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  elif [ -f usr/share/locale/$ll/LC_MESSAGES/util-linux.mo ]; then
    cp usr/share/locale/$ll/LC_MESSAGES/util-linux.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  fi
  if [ -f  usr/share/locale/$LocaleDir/LC_MESSAGES/nano.mo ]; then
    cp usr/share/locale/$LocaleDir/LC_MESSAGES/nano.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  elif [ -f usr/share/locale/$ll/LC_MESSAGES/nano.mo ]; then
    cp usr/share/locale/$ll/LC_MESSAGES/nano.mo \
    initrd/usr/share/locale/$LocaleDir/LC_MESSAGES
  fi
done
)

# Fourth step: install MO files, include intl packages, rebuild the initrd
# ========================================================================
# Install translations in the initrd
#
# We won't use Slackware color scheme, for dialog,  but our own. 
# Additionally, --noshadow will give us more usable lines and rows.
cp  ../dialog/dialogrc $TMP/initrd/etc
chown -R root:root $ISO/isolinux
# Register the target
cp $ISO/slint/DONOTREMOVEME.TXT $TMP/initrd/.target
rm $TMP/initrd/.installer-version
if [ "$SFX" = "32" ]; then
( cd $TMP/initrd/lib/modules
  for i in $(ls); do
    if [ "$(echo $i|grep smp)" = "" ]; then
      rm -r $i
    fi
  done
)
fi
# Build the initrd
( cd $TMP/initrd
  find . -print | cpio -o --owner root:root -H newc | gzip -9 > $ISO/isolinux/initrd.img
)
mv $ISO/isolinux/initrd.img $ISO/isolinux/initrd
# Fifth step: build the ISO file
# ==============================
#
if [ "$SFX" = "64" ]; then
  cp $ISO/isolinux/initrd $ISO/EFI/BOOT
  ( cd $ISO
  size=$(BLOCKSIZE=1M du -s EFI|sed "s/\([[:digit:]][[:digit:]]\).*/\1/")
  rsize=$(( $size + 1 ))
  dd if=/dev/zero of=efiboot.img bs=1M count=$rsize
  # Format the image as FAT16:
  mkfs.fat efiboot.img
  # Create a temporary mount point:
  MOUNTPOINT=$(mktemp -d)
  # Mount the image there:
  mount -o loop efiboot.img $MOUNTPOINT
  # Copy the the whole EFI directory to the mountpoint as elilo needs to
  # find everything it deals with there.
  # On the other hand, no need to include EFI in the ISO.
  cp -r EFI $MOUNTPOINT
  # Unmount and clean up:
  umount $MOUNTPOINT
  rmdir $MOUNTPOINT
  # Move the efiboot.img to ../../isolinux:
  mv efiboot.img $ISO/isolinux
  )
fi
( cd $ISO
# Now $ISO contains all files to be put on the ISO image, so we can
# complete $ISO/CONTENT.TXT with the file tree
sed -i "s/<version>/${SFX}-${SLINTVERSION}$SUFFIX/g" CONTENT.TXT
tree >> CONTENT.TXT
if [ "$SFX" = "64" ]; then
  EFIOPTIONS="-eltorito-alt-boot -e isolinux/efiboot.img -isohybrid-gpt-basdat -no-emul-boot"
fi
xorriso -as mkisofs \
    -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
    -hide-rr-moved \
    -U \
    -V "ISO$sfx_CURRENT" \
    -J \
    -joliet-long \
    -r \
    -v \
    -x EFI \
    -x kernels \
    -o $PATHTOISO \
    -b isolinux/isolinux.bin \
    -c isolinux/boot.cat \
    -no-emul-boot \
    -boot-info-table $EFIOPTIONS . \
)  2>${PATHTOISO%iso}log.txt
chown -R `stat -c %U:%G $CWD` $PATHTOISO ${PATHTOISO%iso}log.txt $ISO
printf "%b" "** Completed. ***

If writing the ISO was successful an hybrid DVD/USB image:
$PATHTOISO is ready.\n"
#rm -r $TMP

