#!/bin/bash

# Copyright 2009, 2010, 2011, 2012  Eric Hameleers, Eindhoven, NL
# Copyright 2026  Patrick J. Volkerding, Sebeka, Minnesota, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

TMP=${TMP:-/tmp}
# mktemp uses this:
export TMPDIR=$TMP

showhelp() {
  echo "# "
  echo "# This script will create an ISO image from the Slackware tree which"
  echo "# can be written to a USB flash drive or burned to optical media (if"
  echo "# it fits). The output can be a file, or it can be sent directly to"
  echo "# a USB flash drive."
  echo "# "
  echo "# $(basename $0) accepts the following parameters:"
  echo "#   -h|--help                  This help."
  echo "#   -i|--infile <filename>     Path to the initrd.img file, if you don't"
  echo "#                              want to use the one in isolinux/"
  echo "#   -o|--outdev <filename>     Output filename, or a device such as"
  echo "#                              /dev/sda to write directly to."
  echo "#                              If not specified, we'll write the image"
  echo "#                              to a file in your $TMP directory."
  echo "#   -s|--slackdir <dir>        Use 'dir' as the root of Slackware tree"
  echo "#   -t|--type                  Type of image to make. The choices are"
  echo "#                              minimal (just the installer), install"
  echo "#                              (also include all installable packages),"
  echo "#                              and complete (include everything)."
  echo "#                              If not specified, the default is minimal."
  echo "# "
  echo "# Examples:"
  echo "# "
  echo "# $(basename $0) -s /home/ftp/pub/slackware-16.0 -i initrd.img -t minimal -o usbboot.img"
  echo "# $(basename $0) -s /home/ftp/pub/slackware-16.0 -t install -o /tmp/slackware-16.0-install.img"
  echo "# $(basename $0) -s /home/ftp/pub/slackware-16.0 -t install -o /dev/sdX"
  echo "# "
  echo "# The second example shows how to create a fully functional Slackware"
  echo "# installer on a USB stick (it needs a Slackware tree as the source)."
  echo "# "
}

# Default image type to create:
TYPE=minimal

# Parse the commandline parameters:
if [ -z "$1" ]; then
  showhelp
  exit 1
fi
while [ ! -z "$1" ]; do
  case $1 in
    -h|--help)
      showhelp
      exit
      ;;
    -i|--infile)
      INITRD="$2"
      if [ ! -r "$INITRD" ]; then
        echo "ERROR: --infile $INITRD does not exist."
        exit 1
      fi
      shift 2
      ;;
    -o|--outdev)
      TARGET="$2"
      shift 2
      ;;
    -s|--slackdir)
      REPODIR="$2"
      if [ ! -d "$REPODIR" ]; then
        echo "ERROR: --slackdir $REPODIR does not exist."
        exit 1
      fi
      shift 2
      ;;
    -t|--type)
      TYPE="$2"
      if [ ! "$TYPE" = minimal -a ! "$TYPE" = install -a ! "$TYPE" = "complete" ]; then
        echo "ERROR: --type $TYPE is not a supported installer image type."
      fi
      shift 2
      ;;
    *)
      echo "*** Unknown parameter '$1'!"
      exit 1
      ;;
  esac
done

# Is this slackware64?
if [ -d $REPODIR/slackware64 ]; then
  SLACKNAME="slackware64"
else
  SLACKNAME="slackware"
fi
# Find the Slackware version from aaa_base:
if ls $REPODIR/$SLACKNAME/a/aaa_base-*txz 1> /dev/null 2> /dev/null ; then
  SLACKVERSION="$(echo $(basename $(/bin/ls $REPODIR/$SLACKNAME/a/aaa_base-*txz)) | cut -f 3 -d -)"
else # guess
  SLACKVERSION="666"
fi
# If there's no target specified, come up with one:
if [ -z "$TARGET" ]; then
  TARGET="${TMP}/${SLACKNAME}-${SLACKVERSION}-${TYPE}.img"
fi

if [ ! -z "$INITRD" ]; then
  # We'll need to make a copy of the parts of the --slackdir tree that we need
  # so that we can replace the initrd.img in the isolinux/ directory.
  TMPREPO=$(mktemp -d)
  if [ "$TYPE" = "install" ]; then
    SKIP="--exclude 'source/*'"
  elif [ "$TYPE" = "minimal" ]; then
    SKIP="--exclude 'extra/*' --exclude 'pasture/*' --exclude 'patches/*' --exclude 'slackware/*' --exclude 'slackware64/*' --exclude 'source/*' --exclude 'testing/*' --exclude 'usb-and-pxe-installers/*'"
  fi
  # Copy the repo:
  #rsync -lprvtH $SKIP ${REPODIR}/ ${TMPREPO}/
  if [ "$TYPE" = "minimal" ]; then
    rsync -lprtH --exclude 'extra/' --exclude 'pasture/' --exclude 'patches/' --exclude 'slackware/' --exclude 'slackware64/' --exclude 'source/' --exclude 'testing/' --exclude 'usb-and-pxe-installers/' ${REPODIR}/ ${TMPREPO}/
  elif [ "$TYPE" = "install" ]; then
    rsync -lprtH --exclude 'source/' --exclude 'usb-and-pxe-installers/' ${REPODIR}/ ${TMPREPO}/
  else # complete
    rsync -lprtH --exclude 'usb-and-pxe-installers/' ${REPODIR}/ ${TMPREPO}/
  fi
  # Replace the initrd.img:
  cp -a $INITRD ${TMPREPO}/isolinux/initrd.img
  # Reset the REPODIR var to the new location:
  REPODIR=$TMPREPO
fi

# Pre-remove the output if it's a file:
if [ -f $TARGET ]; then
  rm -f $TARGET
fi

# Make the image:
echo "Writing a Slackware installer of type $TYPE to ${TARGET}..."
if [ "$TYPE" = minimal ]; then
  ( cd $REPODIR
    xorriso -as mkisofs \
      -iso-level 3 \
      -full-iso9660-filenames \
      -R -J -A "$SLACKNAME $SLACKVERSION $TYPE" \
      -hide-rr-moved \
      -v -d -N \
      -eltorito-boot isolinux/isolinux.bin \
      -eltorito-catalog isolinux/boot.cat \
      -no-emul-boot -boot-load-size 4 -boot-info-table \
      -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
      -eltorito-alt-boot \
      -e isolinux/efiboot.img \
      -no-emul-boot -isohybrid-gpt-basdat \
      -m 'extra/' \
      -m 'pasture/' \
      -m 'patches/' \
      -m 'slackware/' \
      -m 'slackware64/' \
      -m 'source/' \
      -m 'testing/' \
      -m 'usb-and-pxe-installers/usbboot.img' \
      -volid "SlackDVD" \
      -output $TARGET \
      .
  )
elif [ "$TYPE" = install ]; then
  ( cd $REPODIR
    xorriso -as mkisofs \
      -iso-level 3 \
      -full-iso9660-filenames \
      -R -J -A "$SLACKNAME $SLACKVERSION $TYPE" \
      -hide-rr-moved \
      -v -d -N \
      -eltorito-boot isolinux/isolinux.bin \
      -eltorito-catalog isolinux/boot.cat \
      -no-emul-boot -boot-load-size 4 -boot-info-table \
      -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
      -eltorito-alt-boot \
      -e isolinux/efiboot.img \
      -no-emul-boot -isohybrid-gpt-basdat \
      -m 'source/' \
      -m 'usb-and-pxe-installers/usbboot.img' \
      -volid "SlackDVD" \
      -output $TARGET \
      .
  )
else # complete
  ( cd $REPODIR
    xorriso -as mkisofs \
      -iso-level 3 \
      -full-iso9660-filenames \
      -R -J -A "$SLACKNAME $SLACKVERSION $TYPE" \
      -hide-rr-moved \
      -v -d -N \
      -eltorito-boot isolinux/isolinux.bin \
      -eltorito-catalog isolinux/boot.cat \
      -no-emul-boot -boot-load-size 4 -boot-info-table \
      -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
      -eltorito-alt-boot \
      -e isolinux/efiboot.img \
      -no-emul-boot -isohybrid-gpt-basdat \
      -volid "SlackDVD" \
      -output $TARGET \
      .
  )
fi
echo "Done writing Slackware installer to $TARGET."

# Clean up any temporary copy that was made:
if [ -d "$TMPREPO" ]; then
  rm -rf "$TMPREPO"
fi
