#!/bin/bash

[ "$EUID" = "0" ] || exec sudo $0 $*

WDIR="$PWD"
[[ "$PWD" == *"/knoppix"* ]] || WDIR="$PWD/knoppix"
OLD_ISO="knoppix.iso"
NEW_ISO="knoppix2.iso"

usage() {
  echo "Usage: $0 [options]" >&2
  echo "Options:" >&2
  echo "  -d directory		project directory ($WDIR)" >&2
  echo "  -i inputimage		original ISO image ($OLD_ISO)" >&2
  echo "			(optional if project exists)" >&2
  echo "  -o outputimage	new ISO image ($NEW_ISO)" >&2
  exit 0
}

die () {

  mount | grep -q '^/dev/cloop' && umount /dev/cloop
  mount | grep -q "^$OLD_ISO" && umount "$OLD_ISO"
  # [ "$WDIR_CREATED" -a -d "$WDIR" ] && rm -rf "$WDIR"

  lsmod | grep -q '^cloop' && rmmod cloop

  STATUS=$1
  shift

  if [ "$STATUS" = "0" ]; then
    echo "$0 $*" >&2
  else
    echo "$0 failed: $*" >&2
  fi
  exit $STATUS
}

mkd () {
  [ -d "$1" ] || mkdir -p "$1" || die "create directory '$1'"
}

### OPTIONS

while [[ "$1" == "-"* ]]; do
  case "$1" in
    -d)
	WDIR=$2
	shift
	;;
    -i)
	OLD_ISO=$2
        INPUT_SET=1
	shift
	;;
    -o)
	NEW_ISO=$2
	shift
	;;
    *)
        [ "$1" = "-h" ] || echo "Unknown option '$1'" >&2
	usage
  esac
  shift
done

if [ ! -d "$WDIR" ]; then
  WDIR_CREATED=1
  mkd "$WDIR"
fi

cd "$WDIR"
echo "Working directory is now '$WDIR'" >&2

### PREPARE

OLD_DIR="$WDIR/mount"
OLD_ISODIR="$OLD_DIR/master"
OLD_CIMG="$OLD_ISODIR/KNOPPIX/KNOPPIX"
OLD_SRCDIR="$OLD_DIR/source"

NEW_DIR="$WDIR"
ISO_DIR="$NEW_DIR/master"
SRC_DIR="$NEW_DIR/source"
CIMG="$ISO_DIR/KNOPPIX/KNOPPIX"

if [ -d "$ISO_DIR" -a -d "$SRC_DIR" -a ! "$INPUT_SET" ]; then

  echo "Using existing project in directory '$WDIR'" >&2

else

  if [ ! -e "$OLD_ISO" ]; then
    echo "Missing original ISO image ($OLD_ISO)" >&2
    [ "$WDIR_CREATED" ] && rmdir "$WDIR"
    usage
  fi

  MINSPACE=2800000
  FREESPACE=`df -k "$WDIR" | sed -ne 's/.*  *\([0-9][0-9]*\)  *[0-9]*%.*/\1/p'`

  if [ "0$FREESPACE" -lt "$MINSPACE" ]; then
    die 3 "Not enough free space in '$WDIR': $FREESPACE KiB ($MINSPACE KiB required)."
  fi

  echo "Copying contents from original ISO image" >&2

  mkd "$OLD_ISODIR"
  mount -o loop -t iso9660 "$OLD_ISO" "$OLD_ISODIR" || die 2 "mounting master ISO image"

  modprobe zlib_inflate || die 2 "installing zlib_inflate module"
  modprobe cloop file="$OLD_CIMG" || die 2 "installing cloop module"

  mkd "$OLD_SRCDIR"
  mount -o loop -t iso9660 /dev/cloop "$OLD_SRCDIR" || die 2 "mounting compressed image"

  ### COPY IN

  echo "Copying contents, please wait..." >&2

  cp -aux "$OLD_SRCDIR/." "$SRC_DIR" || die 2 "Copy contents"

  echo "  Copying master image content -" >&2

  mkd "$ISO_DIR"
  ( cd "$OLD_ISODIR"; find -size -10000k -type f -exec cp -p --parents {} "$ISO_DIR/" \; ) || die 2 "Copying master"

  echo "Copying done." >&2

  echo "Unmounting original images" >&2

  umount "/dev/cloop" || die 2 "unmounting compressed source image"
  rmmod cloop || die 2 "removing cloop module"
  umount "$OLD_ISO" || die 2 "unmounting master ISO image"

  rmdir "$OLD_SRCDIR"
  rmdir "$OLD_ISODIR"
  rmdir "$OLD_DIR"

  echo "Unmounting done." >&2

fi

### EDIT

echo "Master ISO contents are editable in '$ISO_DIR'" >&2
echo "Source ISO contents are editable in '$SRC_DIR'" >&2
echo "You will now be dropped into the source environment." >&2
echo "There you can use dpkg and apt-get to manage packages." >&2
echo "When done, press Control-D." >&2

# correct name resolving
RESVCF="$SRC_DIR/etc/dhcpc/resolv.conf"
[ -f "$RESVCF" ] && mv "$RESVCF" "$RESVCF.real"
cp /etc/resolv.conf "$RESVCF"

# create temporary environment
cat > "$SRC_DIR/.chroot.sh" <<EOF
mount -t proc proc /proc
bash
apt-get clean
umount /proc
EOF

chmod a+x "$SRC_DIR/.chroot.sh"

chroot "$SRC_DIR" "/.chroot.sh"

echo "Cleaning up after chroot" >&2

# clean up temporary environment
rm "$SRC_DIR/.chroot.sh"

# recorrect name resolving
[ -f "$RESVCF.real" ] && mv "$RESVCF.real" "$RESVCF"

# clean up after apt
APT_DIR="$SRC_DIR/var/lib/apt/lists"
rm -f "$APT_DIR/partial/*"
rm -f "$APT_DIR/*" 2>/dev/null
rm -f "$SRC_DIR/var/cache/apt/*.bin"
rm -rf "$SRC_DIR/.rr_moved"

### CREATE ISO

a="x"
while [[ "$a" != [yn]* ]]; do
  echo -n "Create '$NEW_ISO' (y/n)? "
  read a
done

[ "$a" = "y" ] || die 0 "canceled."

echo "Creating compressed image '$CIMG' from '$SRC_DIR'" >&2

mkisofs -R -U -V "KNOPPIX.net filesystem" -P "KNOPPIX tietopaimen.fi" -hide-rr-moved -cache-inodes -no-bak -pad "$SRC_DIR" | create_compressed_fs - 65536 > "$CIMG" 2>"$WDIR/log" || die 2 "see $WDIR/log"

tail -n 4 < "$WDIR/log"
rm "$WDIR/log"

echo "Counting MD5 sums"

( cd "$ISO_DIR"; find -type f -not -name md5sums -not -name boot.cat -exec md5sum {} \; > KNOPPIX/md5sums ) || die 2 "creating MD5 sums in '$ISO_DIR'"

echo "Creating master ISO image '$NEW_ISO' from '$ISO_DIR'" >&2

mkisofs -pad -l -r -J -v -V "KNOPPIX" -b KNOPPIX/boot.img -c KNOPPIX/boot.cat -hide-rr-moved -o "$NEW_ISO" "$ISO_DIR"

echo "New Knoppix image created: $NEW_ISO" >&2

die 0 "done."
