#!/bin/bash

echo >&2
echo "THIS SCRIPT IS DEPRECATED ! USE ITS SUCCESSOR: merge_debian_isos" >&2
echo >&2
echo "The script merge_2_debian_isos still exists only because it was mentioned">&2
echo "in Debian bug 1011343. The successor can merge more than two ISOs.">&2
echo "So do not edit this script to remove this warning and the 'exit 7' line.">&2
echo >&2

exit 7

usage() {
  echo "usage: $(basename "$0") "'\' >&2
  echo "       boot_iso boot_mount add_iso add_mount result_iso [for_dist]" >&2
  echo >&2
  echo "Mounts by sudo the boot_iso at directory boot_mount and add_iso at" >&2
  echo "add_mount, if not already mounted that way. Then both Debian pools" >&2
  echo "and package lists get merged and a new ISO 9660 image result_iso" >&2
  echo "is produced, which must not yet exist." >&2
  echo "If boot_iso is bootable then the new image will be bootable by the" >&2
  echo "same means." >&2
  echo "This script creates the following temporary tree and files which" >&2
  echo "must not yet exist in the current working directory:" >&2
  echo "  ./merged_dists , ./merged_md5sum.txt , ./merged_REAMDE.txt" >&2
  echo "  ./temp_file" >&2
  echo "The optional sixth argument for_dist should only be given if" >&2
  echo "this script refuses to work and proposes to give this argument." >&2
  echo "Exported non-empty variable MERGE_DATE enforces a particular" >&2
  echo "date string in the text which gets prepended to /README.txt ." >&2
  echo "Exported non-empty variable XORRISO overrides command xorriso," >&2
  echo "which may be needed if installed xorriso is older than 1.4.2." >&2
  echo "Example using GNU xorriso-1.5.4 instead of /usr/bin/xorriso:" >&2
  echo "  export XORRISO="'$HOME'"/xorriso-1.5.4/xorriso/xorriso" >&2
  echo "  $(basename "$0") debian-11.2.0-amd64-DVD-1.iso /mnt/iso1 "'\' >&2
  echo "          debian-11.2.0-amd64-DVD-2.iso /mnt/iso2 merged.iso" >&2
}

if test "$#" -lt 5
then
  usage
  exit 1
fi

BOOT_ISO="$1"
BOOT_ISO_MOUNT="$2"
ADD_ISO="$3"
ADD_ISO_MOUNT="$4"
RESULT_ISO="$5"

# The sixth argument is optional
FOR_DIST="$6"


## Check arguments

if test -e "$RESULT_ISO"
then
  echo "--- A file '""$RESULT_ISO""' is already existing." >&2
  echo "--- Will not overwrite it by the resulting ISO image." >&2
  exit 1
fi
if test -e merged_dists || test -e merged_md5sum.txt || test -e temp_file \
   || test -e merged_README.txt
then
  echo "--- At least one of ./merged_dists, ./merged_md5sum.txt, ./temp_file," >&2
  echo "--- or merged_README.txt is already existing. Will not overwrite them." >&2
  exit 1
fi
if test "$BOOT_ISO" = "$RESULT_ISO" || test "$BOOT_ISO" = "$ADD_ISO" || \
   test "$ADD_ISO" = "$RESULT_ISO"
then
  echo "--- At least two of the three given ISO image paths are equal." >&2
  echo "--- boot_iso and add_iso must exist and differ, result_iso must not exist." >&2
  usage
  exit 1
fi 


## Mount and copy out the files which need to be changed

do_mount_1=1
x=$(mount | grep " $BOOT_ISO_MOUNT " | awk '{print $1}')
if test -n "$x"
then
  i1=$(ls -i "$x" | awk '{print $1}')
  i2=$(ls -i "$BOOT_ISO" | awk '{print $1}')
  if test "$i1" = "$i2"
  then
    do_mount_1=0
    echo "Note: Found $BOOT_ISO already mounted at $BOOT_ISO_MOUNT"
  fi
fi
if test "$do_mount_1" = 1
then
  echo "Note: sudo mount $BOOT_ISO $BOOT_ISO_MOUNT"
  sudo mount "$BOOT_ISO" "$BOOT_ISO_MOUNT" || exit 3
fi
cp -a "$BOOT_ISO_MOUNT/dists" merged_dists
cp -a "$BOOT_ISO_MOUNT/md5sum.txt" merged_md5sum.txt
chmod -R u+w merged_dists
chmod u+w merged_md5sum.txt

do_mount_2=1
x=$(mount | grep " $ADD_ISO_MOUNT " | awk '{print $1}')
if test -n "$x"
then
  i1=$(ls -i "$x" | awk '{print $1}')
  i2=$(ls -i "$ADD_ISO" | awk '{print $1}')
  if test "$i1" = "$i2"
  then
    do_mount_2=0
    echo "Note: Found $ADD_ISO already mounted at $ADD_ISO_MOUNT"
  fi
fi
if test "$do_mount_2" = 1
then
  echo "Note: sudo mount $ADD_ISO $ADD_ISO_MOUNT"
  if sudo mount "$ADD_ISO" "$ADD_ISO_MOUNT"
  then
    dummy=dummy
  else
    if test "$do_mount_1"
    then
      sudo umount "$BOOT_ISO_MOUNT"
    fi
    exit 3
  fi
fi


## Helper functions

# Put out the list of checksummed paths as listed in /dists/$dist/Release
extract_checksum_paths() {
  mode=0
  cat "$1" | \
  while true
  do
    read x || break
    if test "$x" = "MD5Sum:" || test "$x" = "SHA1:" \
       || test "$x" = "SHA256:" || test "$x" = "SHA512:"
    then
      if test "$mode" = 0
      then
        mode=1
      elif test "$mode" = 1
      then
  break
      fi
    elif test "$mode" = 1
    then
      echo "$x"
    fi
  done
}

# Put out the part before the first checksum field
extract_release_head() {
  cat "$1" | \
  while true
  do
    read x || break
    if test "$x" = "MD5Sum:" || test "$x" = "SHA1:" \
       || test "$x" = "SHA256:" || test "$x" = "SHA512:"
    then
  break
    fi
    echo "$x"
  done
}


## Determine which Debian release is on BOOT_ISO

dist=
for i in $(ls -1d "$BOOT_ISO_MOUNT"/dists/*)
do
  if test -d "$i"
  then
    if test -L "$i"
    then
continue
    fi
    test -n "$dist" && dist="$dist "
    dist="$dist""$(basename $i)"
  fi
done
if test -z "$dist"
then
  if test -z "$FOR_DIST"
  then
    echo "--- Cannot determine Debian release from directories in /dists" >&2
    echo "--- (You may provide the release name as sixth argument)" >&2
    echo >&2
    usage
    exit 2
  fi
elif test "$(echo "$dist" | wc -w)" -gt 1
then
  if test -z "$FOR_DIST"
  then
    echo "--- More than one Debian release found in /dists: $dist" >&2
    echo "--- (You may provide the release name as sixth argument)" >&2
    echo >&2
    usage
    exit 2
  fi
fi
if test -n "$FOR_DIST"
then
  echo "Note: Overriding release name '$dist' by '""$FOR_DIST""'" >&2
  dist="$FOR_DIST"
fi
if test -d "$BOOT_ISO_MOUNT"/dists/"$dist"
then
  echo "Note: Will work along $BOOT_ISO_MOUNT"/dists/"$dist"/Release >&2
else
  echo "--- Cannot find directory $BOOT_ISO_MOUNT"/dists/"$dist" >&2
  exit 2
fi


## Prepend info to /README.txt

if test -z "$MERGE_DATE"
then
  MERGE_DATE=$(date +'%Y%m%d-%H:%M')
fi
printf 'Result of a run of %s at %s\r\n' \
       "$(basename $0)" "$MERGE_DATE" >temp_file
printf 'Package pools and Packages lists were merged.\r\n' >>temp_file
printf 'The other files stem from the first input ISO.\r\n' >>temp_file
printf '\r\n' >>temp_file
printf 'Input ISO: %s\r\n' "$BOOT_ISO" >>temp_file
head -2 "$BOOT_ISO_MOUNT"/README.txt >>temp_file
printf '\r\n' >>temp_file
printf 'Input ISO: %s\r\n' "$ADD_ISO" >>temp_file
head -2 "$ADD_ISO_MOUNT"/README.txt >>temp_file
printf '\r\n' >>temp_file
printf '%s%s\r\n' " --------------------------------------" \
                  "----------------------------------------" >>temp_file
printf '\r\n' >>temp_file
cat "$BOOT_ISO_MOUNT"/README.txt >>temp_file

mv temp_file merged_README.txt


## Merge package description files with those from "$ADD_ISO"

# /md5sum.txt seems to be the only overall package list
cat merged_md5sum.txt "$ADD_ISO_MOUNT"/md5sum.txt | sort >temp_file
mv temp_file merged_md5sum.txt

# Determine the files which are mentioned with checksum in main Release files
path_list=$( (extract_checksum_paths merged_dists/"$dist"/Release
              extract_checksum_paths "$ADD_ISO_MOUNT"/dists/"$dist"/Release ) \
             | awk '{print $3}' | sort | uniq )

# Merge .gz files (Release should not be merged. Unclear what others need.)
for i in $path_list
do
  if echo "$i" | grep -v '.gz$' >/dev/null
  then
continue
  fi
  if test -e merged_dists/"$dist"/"$i"
  then
    if test -e "$ADD_ISO_MOUNT"/dists/"$dist"/"$i"
    then
      if test "$(gunzip <merged_dists/"$dist"/"$i" | tail -1)" = ""
      then
        empty_line=
      else
        empty_line=echo
      fi
      ( gunzip <merged_dists/"$dist"/"$i"
        $empty_line
        gunzip <"$ADD_ISO_MOUNT"/dists/"$dist"/"$i" ) | gzip >temp_file
      mv temp_file merged_dists/"$dist"/"$i"
    fi
  elif test -e "$ADD_ISO_MOUNT"/dists/"$dist"/"$i"
  then
    if test -e $(dirname merged_dists/"$dist"/"$i")
    then
      dummy=dummy
    else
      mkdir -p $(dirname merged_dists/"$dist"/"$i")
    fi
    cp "$ADD_ISO_MOUNT"/dists/"$dist"/"$i" merged_dists/"$dist"/"$i"
  fi
  test -e temp_file && rm temp_file
done


## Update dists/"$dist"/Release

extract_release_head merged_dists/"$dist"/Release >temp_file

# Re-create  "MD5Sum:", "SHA256:", "SHA512:" sections
for cmd in md5sum sha1sum sha256sum sha512sum
do
  if type "$cmd" >/dev/null
  then
    case "$cmd" in
      md5sum)    echo "MD5Sum:" ;;
      sha1sum)   echo "SHA1:" ;;
      sha256sum) echo "SHA256:" ;;
      sha512sum) echo "SHA512:" ;;
    esac
    for i in $path_list
    do
      file=merged_dists/"$dist"/"$i"
      if test -e "$file"
      then
        sum=$("$cmd" "$file" | awk '{print $1}')
        size=$(stat -c '%s' "$file")
      elif test -e "$file".gz
      then
        sum=$(gunzip <"$file".gz | "$cmd" | awk '{print $1}')
        size=$(gunzip <"$file".gz | wc -c)
      else
    continue
      fi
      list_path=$(echo "$file" | sed -e 's/^merged_dists\/'"$dist"'\///')
      printf ' %s %8ld %s\n' "$sum" "$size" "$list_path" 
    done 
  fi
done >>temp_file

mv temp_file merged_dists/"$dist"/Release


## Produce the new ISO image

if test -z "$XORRISO"
then
  XORRISO=xorriso
fi

"$XORRISO" \
  -indev "$BOOT_ISO" \
  -outdev "$RESULT_ISO" \
  -map "$ADD_ISO_MOUNT"/pool /pool \
  -map merged_dists /dists \
  -map merged_md5sum.txt /md5sum.txt \
  -map merged_README.txt /README.txt \
  -chown_r 0 /dists /md5sum.txt /README.txt -- \
  -chgrp_r 0 /dists /md5sum.txt /README.txt -- \
  -chmod_r a-w /dists /md5sum.txt -- \
  -chmod_r a=r /README.txt -- \
  -boot_image any replay \
  -stdio_sync off \
  -padding included \
  -compliance no_emul_toc


## Clean up

if test "$do_mount_1" = 1
then
  sudo umount "$BOOT_ISO_MOUNT"
fi
if test "$do_mount_2" = 1
then
  sudo umount "$ADD_ISO_MOUNT"
fi

rm -r merged_dists merged_md5sum.txt merged_README.txt

