#!/bin/bash

ulimit -s unlimited

OPTDIR=/var/opt/comb

LOCALES="af_ZA de_DE en_GB en_US en_ZA es_ES fr_FR it_IT nr_ZA nso_ZA pt_PT ss_ZA st_ZA tn_ZA ts_ZA ve_ZA xh_ZA zu_ZA"
LOCALE_BASE="locale-base-en-us locale-base-en-za locale-base-nr-za locale-base-nso-za locale-base-ss-za locale-base-st-za locale-base-tn-za locale-base-ts-za locale-base-ve-za locale-base-zu-za"

MARK_PKG="packagegroup*"

KERNEL_PKG="packagegroup-comb-kernel kernel-modules kernel-module-* kernel-image";
KERNEL_PKG_RASPI="bootfiles kernel-devicetree cryptodev-module rpi-cmdline rpi-config kernel-image-image";
KERNEL_PKG_COMBO=" cryptodev-module kernel-imagebootfs kernel-image-uimage"
KERNEL_PKG_RASPI_DEL="kernel-image-image-5.4.72-v8-5.4.72* kernel-cmdline-5.4.72*"

ARCH=$(cut -d- -f1 /etc/rpm/platform)
CODENAME=$(lsb_release -c |cut -f2)
POKY=$(lsb_release -r |cut -f2)
ARCH_NAME=$(echo ${ARCH} |tr '_' '-')
ARCH_FAMILY=$(echo ${ARCH_NAME} |cut -d- -f1)
REPO="oe-remote-repo"
KERN_VER=${KERN_VER=$(uname -r)}
BASEURL="https://honeycomb.comb-communications.com"

if [ "${ARCH_FAMILY}" == "raspberrypi" ];then
     KERNEL_PKG="${KERNEL_PKG} ${KERNEL_PKG_RASPI}";
     KERNEL_PKG_DEL="${KERNEL_PKG_DEL} ${KERNEL_PKG_RASPI_DEL}"
 elif [ "${ARCH_FAMILY:0:10}" == "stm32mp157" ];then
     KERNEL_PKG="${KERNEL_PKG} ${KERNEL_PKG_COMBO}";
fi;

ARCH_NAME_NS="raspberrypi-cm4-64"
ARCH_NAME_COMBO="stm32mp157f-ns-combo"

if [ "${ARCH_NAME}" == "${ARCH_NAME_COMBO}" ];then
  DEF_IMG_NAME="comb-combo"
 else
  DEF_IMG_NAME="comb-ns"
fi;

TMPDEV="/dev/${DEF_IMG_NAME}-root"

if [ -e ~/${DEF_IMG_NAME} ] || [ ! -d ${OPTDIR} ];then
  DEF_IMG=~/${DEF_IMG_NAME}
 else
  if [ ! -d ${OPTDIR}/${ARCH_NAME}/${DEF_IMG_NAME} ];then
    mkdir -p ${OPTDIR}/${ARCH_NAME}/${DEF_IMG_NAME}
  fi;
  DEF_IMG=${OPTDIR}/${ARCH_NAME}/${DEF_IMG_NAME}
fi;

kernel_repo(){
  if [ ! -e ${1}/var/cache/dnf/${REPO}-${ARCH_NAME}-${CODENAME}-${ARCH}_kernel.solv ];then
    (cat <<__EOF__
[${REPO}-${ARCH_NAME}-${CODENAME}-${ARCH}_kernel]
name=OE Remote Repo: ${ARCH_NAME} ${CODENAME} ${ARCH}_kernel
baseurl=${BASEURL}/${ARCH_NAME}/${CODENAME}/${ARCH}_kernel
gpgcheck=0

__EOF__
    ) > ${1}/etc/yum.repos.d/${REPO}-${ARCH_NAME}-${CODENAME}-kernel.repo
  fi;
}

print_locrepo() {
        cat << __EOF__
[oe-local-repo-${ARCH_NAME}-${CODENAME}-${2}]
name=OE Local Repo: ${ARCH_NAME} ${CODENAME} ${2}
baseurl=file://${1}
gpgcheck=0

__EOF__
}

create_local_repo() {
  for repo in $(uname -m) noarch ${ARCH} ${ARCH}_kernel;do
    BASEDIR=/var/spool/repo/${repo}
    if [ ! -d ${BASEDIR}/repodata ];then
      mkdir -p ${BASEDIR};
      createrepo_c ${BASEDIR} >/dev/null 2>&1
    fi;
    print_locrepo ${BASEDIR} ${repo}
  done
}

check_local_repo() {
  for repo in $(uname -m) noarch ${ARCH} ${ARCH}_kernel;do
    BASEDIR=/var/spool/repo/${repo}
    if [ ! -d ${BASEDIR}/repodata ];then
      mkdir -p ${BASEDIR};
      createrepo_c ${BASEDIR} >/dev/null 2>&1
    fi;
  done
}

mount_sys(){
  for sysdir in dev proc sys run;do
    if [ ! -d ${1}/${sysdir} ];then
      mkdir ${1}/${sysdir}
    fi;
  done;
  mount -t devtmpfs devfs ${1}/dev
  mount -t sysfs sysfs ${1}/sys
  mount -t proc proc ${1}/proc
  mount -t tmpfs none ${1}/run

  if [ ! -d ${1}/var/volatile ];then
    mkdir -p ${1}/var/volatile
  fi;
  mount -t tmpfs none ${1}/var/volatile/
  for voldir in tmp log;do
    if [ ! -d ${1}/var/volatile/${voldir} ];then
      mkdir ${1}/var/volatile/${voldir}
    fi;
  done
  mkdir -p ${1}/run/lock
  mkdir -p ${1}/run/resolvconf
  mount -t devpts none ${1}/dev/pts
}

mk_locale(){
  for locale in ${LOCALES};do
    localedef --replace --add-to-archive --prefix=${1}/ -f UTF-8  ${1}/usr/lib/locale/${locale}
  done

  localedef --replace --add-to-archive --prefix=${1}/ -f iso-8859-1 ${1}/usr/lib/locale/fr_FR.ISO-8859-1
  localedef --replace --add-to-archive --prefix=${1}/ -f iso-8859-2 ${1}/usr/lib/locale/pl_PL.ISO-8859-2
  localedef --replace --add-to-archive --prefix=${1}/ -f iso-8859-9 ${1}/usr/lib/locale/tr_TR.ISO-8859-9
  localedef --replace --add-to-archive --prefix=${1}/ -f euc-jp  ${1}/usr/lib/locale/ja_JP.EUC-JP
  localedef --replace --add-to-archive --prefix=${1}/ -f big5-hkscs  ${1}/usr/lib/locale/zh_HK.BIG5-HKSCS
}

kern_depmod(){
  for kver in $(ls ${1}/lib/modules/);do
    depmod -b ${1}/ -a ${kver}
  done
}

kern_quick_install(){
  dnf ${DNF_OPT} --destdir=${1} --downloadonly install kernel-modules
  (rpm --root=${2}/ --replacefiles --noscripts -i ${1}/*.rpm && rm ${1}/*.rpm) 2>/dev/null

  dnf ${DNF_OPT} --destdir=${1} --downloadonly install ${KERNEL_PKG}
  (rpm --root=${2}/ --replacefiles --noscripts -i ${1}/*.rpm && rm ${1}/*.rpm) 2>/dev/null

  kern_depmod ${2}
}

kern_quick_update(){
  dnf ${DNF_OPT} --destdir=${1} --downloadonly update kernel-module*
  (rpm --root=${2}/ --replacefiles --noscripts --replacefiles --replacepkgs -U ${1}/*.rpm && rm ${1}/*.rpm) 2>/dev/null

  dnf ${DNF_OPT} --destdir=${1} --downloadonly update ${KERNEL_PKG}
  (rpm --root=${2}/ --replacefiles --noscripts --replacefiles --replacepkgs -U ${1}/*.rpm && rm ${1}/*.rpm) 2>/dev/null

  kern_depmod ${2}
}

check_poky() {
  case ${1} in
    "3.1.9" |"3.1.16" | "3.1.22")
      return 0
      ;;
    *)
      return 1
      ;;
  esac;
}

post_install(){
  if [ ! -e ${1}/usr/lib/locale/locale-archive ];then
    mk_locale ${1}
  fi;

  if [ ! -e ${1}/boot/config.txt ] && [ -e ${1}/boot/config.orig ];then
    (grep -vE "^(dtoverlay|#|$)" ${1}/boot/config.orig
    grep -E "^dtoverlay" ${1}/boot/config.orig) > ${1}/boot/config.txt
  fi;

  if [ ! -e ${1}/boot/cmdline.txt ] && [ -e ${1}/boot/cmdline.orig ];then
    install -m 0644 ${1}/boot/cmdline.orig ${1}/boot/cmdline.txt
  fi;

  rm -f  ${1}/etc/*- ${1}/etc/.pwd.lock
  if ! grep vm.min_free_kbytes ${1}/etc/sysctl.conf >/dev/null ;then
    printf '\nvm.min_free_kbytes = 8192\n' >> ${1}/etc/sysctl.conf
  fi

  #Empty locale files to make sure they installed
  dnf ${DNF_OPT} install ${LOCALE_BASE} \
	`dnf list |grep -E "^(glibc|gtk\+3)-locale-(en|en-za|en-gb|en-us|fr|de|pt|zu|af|es|it|nr|nso|ss|st|tn|ts|ve|xh|zu)\." |awk '{printf "%s ",$1}'`

  if [ "${1}" ] && [ "${1}" != "/" ];then
    sed -i '/^$/d' ${1}/usr/lib/ssl-1.1/certs/ca-certificates.crt
  fi;

  if [ ! -e ${1}/usr/share/icons/Adwaita/icon-theme.cache ];then
    dnf ${DNF_OPT} reinstall adwaita-icon-theme* && dnf ${DNF_OPT} install adwaita-icon-theme*
  fi;

  if [ ! -e ${1}/etc/timestamp ];then
    date -u +%4Y%2m%2d%2H%2M%2S  > ${1}/etc/timestamp
  fi;

  if [ ! -d ${1}/mnt/legato ];then
    mkdir -p ${1}/mnt/legato
  fi;

  check_poky ${POKY}
}

kern_update() {
    DLDIR=$(mktemp -d -p ~ rpmdl-XXXXXXXXX)

    for RMRPM in ${KERNEL_PKG_DEL};do
        rpm  -e --justdb --nodeps --noscripts ${RMRPM} > /dev/null 2>&1
    done

    kern_quick_update ${DLDIR} ${1}
    kern_quick_install ${DLDIR} ${1}

    if [ "${DLDIR}" ] && [ -d ${DLDIR} ];then
       rm -rf ${DLDIR}
    fi;
}

run_update() {
    echo "Update packages"
    kern_update ${1}
    dnf ${DNF_OPT} --exclude legato --exclude bootfiles --exclude kernel-image-* --exclude kernel-devicetree update
    dnf ${DNF_OPT} update legato

    post_install ${1}

    if [ ! "${1}" ] && [ -e /run/initctl ];then
      echo "Rebooting"
      /sbin/reboot
    fi;
}

dnf_update() {
  echo "Checking DB"
  if ! rpm --root=${1}/ --verifydb;then
    rpm --root=${1}/ --rebuilddb;
  fi;

  echo "Checking Install"
  if ! rpm --root=${1}/ -q packagegroup-comb >/dev/null;then
    kern_update ${1}
    dnf  ${DNF_OPT} install packagegroup-comb
    run_update ${1}
  fi

  echo "Checking App"
  if ! rpm --root=${1}/ -q packagegroup-comb-legato >/dev/null ;then
    kern_update ${1}
    dnf  ${DNF_OPT} install legato
    run_update ${1}
  fi

  echo "Checking updates"
  if [ ! -e /etc/yum.repos.d/oe-local-repo-${ARCH_NAME}-${CODENAME}.repo ];then
    create_local_repo > /etc/yum.repos.d/oe-local-repo-${ARCH_NAME}-${CODENAME}.repo
   else
    check_local_repo
  fi;

  (dnf ${DNF_OPT} repolist && kernel_repo ${1}) > /dev/null 2>&1
  dnf ${DNF_OPT} --refresh check-update
  if [ $? -eq 100 ];then
    run_update ${1}
   else
    post_install ${1}
  fi

  if rpm --root=${1}/ -q packagegroup-comb-dunfell >/dev/null;then
    dnf ${DNF_OPT} --noautoremove erase packagegroup-comb-dunfell
  fi;
  dnf ${DNF_OPT} mark install ${MARK_PKG}
}

mkroot_base(){
  DLDIR=$(mktemp -d -p ~ rpmdl-XXXXXXXXX)

  echo "Download core rootfs files (${DLDIR})"
  dnf ${DNF_OPT} --destdir=${DLDIR} --downloadonly install base-files sysvinit busybox

  echo "Install core rootfs files without scripts"
  (rpm --root=${1} --noscripts -i ${DLDIR}/*.rpm && rm -rf ${1}/var/lib/rpm) 2>/dev/null

  echo "Install core rootfs files with scripts"
  dnf ${DNF_OPT} install base-files busybox util-linux-mountpoint util-linux-nologin procps
  dnf ${DNF_OPT} install sysvinit shadow
  dnf ${DNF_OPT} --destdir=${DLDIR} --downloadonly clean packages

  echo "Install kernel/kernel modules without scripts for each module"
  kern_quick_install ${DLDIR} ${1}

  if [ "${DLDIR}" ] && [ -d ${DLDIR} ];then
     rm -rf ${DLDIR}
  fi;

  if [ ! -d ${1}/run/lock ];then
    mkdir -p ${1}/run/lock
  fi;

  echo "Install packages"
  dnf ${DNF_OPT} install packagegroup-comb-dunfell
  dnf ${DNF_OPT} --noautoremove erase packagegroup-comb-dunfell alsa-state
  dnf ${DNF_OPT} install alsa-state
  dnf ${DNF_OPT} reinstall adwaita-icon-theme*
  dnf ${DNF_OPT} mark install ${MARK_PKG}

  post_install ${1}
}

cleanup_img(){
  umount ${2}/boot ${2}

  if [ "${1}" ] && [ -b ${1} ];then
    if losetup -d ${1};then
      rm -f ${1}p?
    fi;
  fi;
}

fdisk_combo() {
  parted -a none -s ${1} \
    mklabel gpt \
    mkpart fip 1024s 9215s \
    mkpart boot ext4 9216s 140287s \
    mkpart rootfs ext4 140288s 100% \
    set 2 legacy_boot on
  sgdisk ${1} -u 5:e91c4e10-16e6-4c0e-bd0e-77becf4a3582
}

fdisk_ns() {
  parted -s ${1} \
    mklabel msdos \
    mkpart primary fat32 1M 100M \
    mkpart primary ext4 100M 100%
}

fsck_combo() {
  if [ -b ${1}p3 ];then
    e2fsck -C 0 -fy ${1}p2
    e2fsck -C 0 -fy ${1}p3
   else
    e2fsck -C 0 -fy ${1}2
    e2fsck -C 0 -fy ${1}3
  fi
}

fsck_ns() {
  if [ -b ${1}p2 ];then
    fsck.fat -a ${1}p1
    e2fsck -C 0 -fy ${1}p2
   else
    fsck.fat -a ${1}1
    e2fsck -C 0 -fy ${1}2
  fi;
}

mkfs_combo() {
  mkfs.ext4 ${1}p2 -b 1024 -L boot
  mkfs.ext4 ${1}p3 -L rootfs
}

mkfs_ns() {
  mkfs.vfat ${1}p1 -n BOOT
  mkfs.ext4 ${1}p2 -L ROOT
}

mkimg_ns() {
  dd status=progress if=/dev/zero of=${1} bs=1M count=1536
  fdisk_ns ${1}
}

unpack_ns_img_combo() {
  dd status=progress if=/dev/zero of=${1}.img bs=1M count=1026
  LOOP=$(losetup -f -P --show ${1}.img)

  dd conv=notrunc,nocreat if=${1}.img.pack status=progress bs=1K skip=17 count=70144 of=${LOOP}

  fdisk_combo ${LOOP}
  mkfs_combo ${LOOP}

  e2image -pra -o 4718592 ${1}.img.pack ${LOOP}p2
  e2image -pra -o 71827456 ${1}.img.pack ${LOOP}p3

  echo "Checking File System"
  fsck_combo ${LOOP}
  echo "Expanding File System"
  resize2fs ${LOOP}p2
  resize2fs ${LOOP}p3
  losetup -d ${LOOP}
}

unpack_ns_img_raspi() {
  mkimg_ns ${1}.img

  LOOP=$(losetup -f -P --show ${1}.img)

  mkfs_ns ${LOOP}

  dd conv=notrunc,nocreat if=${1}.img.pack status=progress bs=1M skip=1 count=94 of=${LOOP}p1
  e2image -pra -o 99614720 ${1}.img.pack ${LOOP}p2

  echo "Checking File System"
  fsck_ns ${LOOP}
  echo "Expanding File System"
  resize2fs ${LOOP}p2
  losetup -d ${LOOP}
}

unpack_ns_img() {
  if [ -e ${1}.img.pack ] && [ -e ${1}.img.pack.xz ] && [ ${1}.img.pack.xz -nt ${1}.img.pack ];then
    rm ${1}.img.pack
    xz -d -k --verbose ${1}.img.pack.xz || return 1
   elif [ ! -e ${1}.img.pack ] && [ -e ${1}.img.pack.xz ] && [ ${1}.img.pack.xz -nt ${1}.img.pack ];then
    xz -d -k --verbose ${1}.img.pack.xz || return 1
   elif [ ! -e ${1}.img.pack ];then
    return 1
  fi

  LOOP=$(losetup -f -P --show ${1}.img.pack)
  if [ -b ${LOOP}p3 ];then
    losetup -d ${LOOP}
    unpack_ns_img_combo ${1}
  else
    losetup -d ${LOOP}
    unpack_ns_img_raspi ${1}
  fi
  if [ ! -d ${1} ];then
    mkdir ${1}
  fi;
}

create_ns_image() {
  if check_ns_img ${1};then
    echo "Image exits"
    exit 1
  fi;

  if [ ! -d ${1} ];then
    mkdir -p ${1}
  fi;

  if [ ! -e ${1}.tar.bz2 ] && ! wget ${BASEURL}/${ARCH_NAME_NS}/${CODENAME}/img/core-image-comb-${ARCH_NAME_NS}.tar.bz2 -O ${1}.tar.bz2;then
    rm ${1}.tar.bz2
    exit 1
  fi;

  mkimg_ns ${1}.img

  LOOP=$(losetup -P -f --show ${1}.img)
  if [ ! "${LOOP}" ];then
    echo "Could not allocate loop device"
    rm -rf ${1} ${1}.img
    return 1
  fi;

  mkfs_ns ${LOOP}

  if ! mount ${LOOP}p2 ${1};then
    losetup -d ${LOOP}
    rm -rf ${1} ${1}.img
  fi;

  mkdir ${1}/boot
  if ! mount ${LOOP}p1 ${1}/boot;then
    umount ${1}
    losetup -d ${LOOP}
    rm -rf ${1} ${1}.img
  fi;

  tar -C ${1} -xf ${1}.tar.bz2

  umount ${1}/boot ${1}
  losetup -d ${LOOP}
}

create_combo_image() {
  if check_ns_img ${1};then
    echo "Image exits"
    exit 1
  fi;

  if [ ! -d ${1} ];then
    mkdir -p ${1}
  fi;

  if [ ! -e ${1}.img.bz2 ] && ! wget ${BASEURL}/${ARCH_NAME_COMBO}/${CODENAME}/img/core-image-comb-${ARCH_NAME_COMBO}.wic.bz2 -O ${1}.img.bz2;then
    rm ${1}.img.bz2
    exit 1
  fi;

  bunzip2 -k ${1}.img.bz2
}

pack_ns_img_combo() {
  for lcnt in 1 2 3;do
    fsck_combo ${2}
    resize2fs -p -M ${2}p2
    resize2fs -p -M ${2}p3
  done

  e2image -pra -O 71827456 ${2}p3 ${1}.img.pack
  resize2fs -p ${2}p2
  resize2fs -p ${2}p3
  losetup -d ${2}

  dd status=progress conv=nocreat,notrunc if=${1}.img bs=1K count=70143 of=${1}.img.pack
  dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=1 of=${1}.img.pack

  LOOP=$(losetup -f -P --show ${1}.img.pack)

  fdisk_combo ${LOOP}

  fsck_combo ${LOOP}
  resize2fs -p ${LOOP}p2
  resize2fs -p ${LOOP}p3

  losetup -d ${LOOP}
}

pack_ns_img_raspi() {
  for lcnt in 1 2 3;do
    e2fsck -C 0 -fy ${2}p2
    resize2fs -p -M ${2}p2
  done

  fsck_ns ${2}
  e2image -pra -O 99614720 ${2}p2 ${1}.img.pack
  resize2fs -p ${2}p2
  losetup -d ${2}

  dd status=progress conv=nocreat,notrunc if=${1}.img bs=1M count=95 of=${1}.img.pack
  dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=1 of=${1}.img.pack
  LOOP=$(losetup -f -P --show ${1}.img.pack)

  fdisk_ns ${LOOOP}
  fsck_ns ${LOOP}
  resize2fs -p ${LOOP}p2
  losetup -d ${LOOP}
}

pack_ns_img() {
  if ! check_ns_img ${1};then
    echo "Image not found"
    return 1;
  fi;

  if [ -e ${1}.img.pack ] && [ ${1}.img.pack -nt ${1}.img ];then
    echo "Already packed"
    return 0;
  fi;

  if [ -e ${1}.img.pack ];then
    rm ${1}.img.pack
  fi;

  LOOP=$(losetup -f -P --show ${1}.img)
  if [ -b ${LOOP}p3 ];then
    pack_ns_img_combo ${1} ${LOOP}
   else
    pack_ns_img_raspi ${1} ${LOOP}
  fi;
}

xz_pack_ns_img() {
  if [ ! "${1}" ] || [ ! -e ${1}.img.pack ];then
    echo "Image not found"
    return 1;
  fi;

  if [ -e ${1}.img.pack.xz ] && [ ${1}.img.pack.xz -nt ${1}.img.pack ];then
    echo "Already compressed"
    return 0;
  fi;

  if [ ! -e ${1}.img.pack.xz ] || [ ${1}.img.pack -nt ${1}.img.pack.xz ];then
    if [ -e ${1}.img.pack.xz ];then
      rm ${1}.img.pack.xz
    fi;
    xz -T 0 -k --verbose ${1}.img.pack
    touch ${1}.img.pack.xz
  fi;
}


check_ns_img() {
  if [ ! "${1}" ];then
     return 1
   elif [ -b "${1}" ];then
     return 0
   elif [ -e "${1}.img" ];then
     return 0
   elif [ ! -e ${1}.img.pack ] && [ ! -e ${1}.img.pack.xz ];then
     return 1
  fi;

  unpack_ns_img ${1} || exit 1
}

install_root(){
  DNF_OPT="-y -q --installroot=${1}"

  if ! check_ns_img ${1};then
    mkimg_ns ${1}.img
    BLKDEV=$(losetup --show -P -f ${1}.img)
    mkfs_ns ${BLKDEV}
  elif [ -e ${1}.img ];then
    BLKDEV=$(losetup --show -P -f ${1}.img)
   else
    echo "Imgage file not found"
    exit
  fi;

  if [ ! "${BLKDEV}" ];then
    echo "Image file not loaded"
    exit;
  fi;

  if [ ! -d ${1} ];then
    mkdir -p ${1}
  fi;

  if [ -b ${BLKDEV}p3 ];then
    ROOT_PART=${BLKDEV}p3
    BOOT_PART=${BLKDEV}p2
   else
    ROOT_PART=${BLKDEV}p2
    BOOT_PART=${BLKDEV}p1
  fi

  if mount ${ROOT_PART} ${1};then
    if [ ! -d ${1}/boot ];then
      mkdir -p ${1}/boot
    fi;
    if ! mount ${BOOT_PART} ${1}/boot;then
       echo "Image file boot not mounted"
       cleanup_img ${BLKDEV} ${1}
       exit
    fi;
   else
     echo "Image file not mounted"
     cleanup_img ${BLKDEV} ${1}
     exit
  fi;

  if [ ! -e ${1}/etc/dnf/dnf.conf ];then
    echo "Add RPM/DNF files to new root"
    rsync -aR /etc/rpmrc /etc/rpm /etc/dnf /etc/yum.repos.d ${1}/
  fi;

  mount_sys ${1}

  if [ ! -d ${1}/bin ];then
    mkroot_base ${1}
   else
    if ! dnf ${DNF_OPT} --installed list packagegroup-comb-dunfell > /dev/null 2>&1;then
      dnf ${DNF_OPT} install packagegroup-comb-dunfell
      dnf ${DNF_OPT} reinstall alsa-state adwaita-icon-theme*
      dnf_update ${1}
      post_install ${1}
     else
      dnf_update ${1}
    fi;
  fi;

  for sysdir in dev/pts dev proc sys var/volatile/ run;do
      umount ${1}/${sysdir}
  done;

  dnf ${DNF_OPT} clean all

  if [ -e ${1}/etc/volatile.cache ];then
      rm  ${1}/etc/volatile.cache
  fi;

  dnf ${DNF_OPT} --installed list |awk '{printf "%s\n",$1}' |sort > list.newroot
  dnf -q --installed list |awk '{printf "%s\n",$1}' |sort > list

  cleanup_img ${BLKDEV} ${1}
}

wpnetlink_stop() {
  if [ -x /etc/init.d/wpnetlink ] && /etc/init.d/wpnetlink status;then
    /etc/init.d/wpnetlink stop
    if /etc/init.d/wpnetlink status >/dev/null 2>&1;then
      killall -9 wpnetlink
    fi;
    if /etc/init.d/wpnetlink status;then
      echo "wpnetlink not stopped"
      exit 1;
    fi;
    touch /tmp/wpnetlink-start
  fi;
}

wpnetlink_start() {
    if [ -x /etc/init.d/wpnetlink ] && [ -e /tmp/wpnetlink-start ];then
      rm /tmp/wpnetlink-start
      /etc/init.d/wpnetlink start
    fi;
}

mount_ns_board() {
  if [ -e ${TMPDEV} ];then
   umount_image ${1}
    return 0
  fi;

  if [ ! -d ${1} ];then
    mkdir -p ${1}
  fi;

  wpnetlink_stop

  rpiboot
  echo "Waiting For Flash"
  sleep 10
  for FLASH in /dev/sd?;do
    continue;
  done;

  if [ ! "${FLASH}" ] || [ ! -b "${FLASH}" ];then
    wpnetlink_start
    echo "Block device does not exit"
    return 1;
  fi

  ln -s ${FLASH} ${TMPDEV}

  fsck_ns ${FLASH}

  mount ${FLASH}2 ${1}
  mount ${FLASH}1 ${1}/boot

  mount_sys ${1}
}

mount_image() {
  if [ -e ${TMPDEV} ] && [ ! -b ${1} ];then
    echo "Already mounted"
    exit 1
  elif [ -b ${1} ] && [ -d /mnt/etc ];then
    echo "Already mounted"
    exit 1
  fi;

  if ! check_ns_img ${1};then
    echo "Image missing"
  fi;

  if [ -b ${1} ];then
    MNTPNT=/mnt
  elif [ ! -d ${1} ];then
    echo "Directory missing"
    exit 1
  else
    MNTPNT=${1}
  fi;

  if [ ! -b "${1}" ];then
    LOOP=$(losetup -f)
    losetup -P ${LOOP} ${1}.img
    ln -s ${LOOP} ${TMPDEV}
  else
    LOOP=${1};
  fi;

  if [ -b ${LOOP}p3 ];then
    mount ${LOOP}p3 ${MNTPNT}
    mount ${LOOP}p2 ${MNTPNT}/boot
   elif [ -b ${LOOP}3 ];then
    mount ${LOOP}3 ${MNTPNT}
    mount ${LOOP}2 ${MNTPNT}/boot
   elif [ -b ${LOOP}p2 ];then
    mount ${LOOP}p2 ${MNTPNT}
    mount ${LOOP}p1 ${MNTPNT}/boot
   elif [ -b ${LOOP}2 ];then
    mount ${LOOP}2 ${MNTPNT}
    mount ${LOOP}1 ${MNTPNT}/boot
  fi

  mount_sys ${MNTPNT}
}

umount_image(){
  wpnetlink_start

  if [ ! -e ${TMPDEV} ] && [ ! -b ${1} ];then
    echo "Not mounted"
    exit 1
  fi;

  if [ -b ${1} ];then
    MNTPNT=/mnt
  elif [ ! -d ${1} ];then
    echo "Directory missing"
    exit 1
  else
    MNTPNT=${1}
  fi;

  for sysdir in /dev/pts /dev /proc /sys /var/volatile /boot /run;do
    umount  ${MNTPNT}${sysdir}
  done;
 umount  ${MNTPNT} || return 1

  if [ ! -b ${1} ] && losetup ${TMPDEV} >/dev/null 2>&1;then
    losetup -d ${TMPDEV}
  fi;
  if [ ! -b ${1} ];then
    rm ${TMPDEV}
  fi;
}

diff_image() {
  if [ ! -e ${TMPDEV} ];then
    echo "Not mounted"
    exit 1
  fi;

  if [ ! -d ${1} ];then
    echo "Directory missing"
    exit 1
  fi;

  diff -x home -x dev -x sys -x proc -x var -x run -x mnt -x legato -x data -x etc -x tmp -qr ${1} / |grep -v __pycache__
  diff -x passwd -x shadow -x group -x gshadow -x ld.so.cache -x ca-certificates.crt -x group- -x shadow- -x passwd- -x .pwd.lock \
       -x gshadow- -x default -x ssh -x timestamp -x *.lock~~XXXXXX -ur ${1}/etc /etc/
}

fix_duoplicates() {
  DLDIR=$(mktemp -d -p ~ rpmdl-XXXXXXXXX)

  if [ ! "${DLDIR}" ] || [ ! -d ${DLDIR} ];then
    return 1
  fi;

  #Handle kernel Modules
  if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} kernel-module*;then
    rpm --nodeps --root=${1}/ --noscripts --force -U ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} kernel-module*;then
      rpm --nodeps --root=${1}/ --noscripts --force -i --reinstall  ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    fi;
    kern_depmod ${1}
  fi;
  rm ${DLDIR}/*.rpm

  #Handle kernel
  if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} ${KERNEL_PKG};then
    rpm --nodeps --root=${1}/ --noscripts --force -U ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} ${KERNEL_PKG};then
      rpm --nodeps --root=${1}/ --noscripts --force -i --reinstall  ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    fi;
  fi;
  rm ${DLDIR}/*.rpm

  #Handle non legato apps
  if dnf ${DNF_OPT}  remove --duplicates --downloadonly --exclude=packagegroup-comb-legato --exclude=legato --destdir=${DLDIR};then
    rpm --nodeps --root=${1}/ --force --replacefiles --replacepkgs -U ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    if dnf ${DNF_OPT}  remove --duplicates --downloadonly --exclude=packagegroup-comb-legato --exclude=legato --destdir=${DLDIR};then
      rpm --nodeps --root=${1}/ --force -i --reinstall  ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    fi;
  fi;

  #Fixup LEgato
  if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} packagegroup-comb-legato legato;then
    rpm --nodeps --root=${1}/ --force --replacefiles --replacepkgs -U ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    if dnf ${DNF_OPT}  remove --duplicates --downloadonly --destdir=${DLDIR} packagegroup-comb-legato legato;then
      rpm --nodeps --root=${1}/ --force -i --reinstall  ${DLDIR}/*.rpm && rm ${DLDIR}/*.rpm
    fi;
  fi;

  rm -rf ${DLDIR}
}

reinstall_pkg() {
  echo "Reinstall Packages"
  dnf ${DNF_OPT} --refresh check-update
  dnf ${DNF_OPT} --exclude kernel* --exclude legato --exclude util-linux* --exclude procps --exclude coreutils --exclude ca-certificates --exclude lsb-release --exclude sysvinit* --exclude shadow* reinstall '*' || return 1
}

reinstall_cacerts() {
  DLDIR=$(mktemp -d -p /tmp rpmdl-XXXXXXXXX)
  if [ ! "${DLDIR}" ] || [ ! -d ${DLDIR} ];then
    return 1
  fi;

  echo "Reinstall CA Certs"
  dnf ${DNF_OPT} --refresh check-update
  (dnf ${DNF_OPT} --downloadonly --destdir=${DLDIR} reinstall ca-certificates && \
	rm -rf ${1}/etc/ssl/certs/* && rpm --root=${1}/ --quiet -i --reinstall ${DLDIR}/ca-certificates* && \
	sed -i '/^$/d' ${1}/usr/lib/ssl-1.1/certs/ca-certificates.crt) || (rm -rf ${DLDIR};return 1)

  rm -rf ${DLDIR}
}

reinstall_clean() {
  echo "Erase Unused"
  dnf ${DNF_OPT} --refresh check-update
  dnf ${DNF_OPT} --noautoremove erase util-linux-raw libsrtp2-2 kernel-cmdline.${ARCH} perl-module-unicode-collate-locale*
  rpm --root=${1}/ --noscripts -e `dnf --installed list kernel*5.4.72-v8 |grep -E "^kernel.*\-5.4.72-v8" |awk '{print $1}' `
  rm -rf ${1}/lib/modules/5.4.72-v8/
}

combo_flash_boot() {
  ARCH_SUF=$(echo ${ARCH} |cut -d_ -f2-)
  DT_NAME=${ARCH_FAMILY}-comb_${ARCH_SUF}-mx

  for boot in boot0 boot1;do
    if [ -e /sys/class/block/mmcblk0${boot}/force_ro ] && [ -e /boot/arm-trusted-firmware/tf-a-${DT_NAME}-emmc.stm32 ];then
      echo 0 > /sys/class/block/mmcblk0${boot}/force_ro ;dd if=/boot/arm-trusted-firmware/tf-a-${DT_NAME}-emmc.stm32 of=/dev/mmcblk0${boot}
    fi;
  done;
  if [ -b /dev/mmcblk0p1 ] && [ -b /dev/mmcblk0p1 ] && [ -e /boot/fip/fip-${DT_NAME}-trusted.bin ];then
    dd if=/boot/fip/fip-${DT_NAME}-trusted.bin of=/dev/mmcblk0p1
  fi;

}

reinstall_alt() {
  echo "Reinstall Alt Packages"
  dnf ${DNF_OPT} --refresh check-update
  dnf ${DNF_OPT} reinstall util-linux-mountpoint util-linux-nologin || return 1
  for alt in procps sysvinit;do
    dnf ${DNF_OPT} reinstall ${alt}* || return 1
  done
  dnf ${DNF_OPT} --exclude util-linux-mountpoint --exclude util-linux-nologin reinstall util-linux* || return 1
  for alt in shadow coreutils;do
    dnf ${DNF_OPT} reinstall ${alt}* || return 1
  done
}

reinstall_kern() {
  DLDIR=$(mktemp -d -p ~ rpmdl-XXXXXXXXX)
  if [ ! "${DLDIR}" ] || [ ! -d ${DLDIR} ];then
    return 1
  fi;

  echo "Reinstall Kernel"
  dnf ${DNF_OPT} --refresh check-update
  if [ -d ${1}/lib/modules/${KERN_VER} ];then
    dnf ${DNF_OPT} --downloadonly --destdir=${DLDIR} reinstall kernel-module*${KERN_VER} kernel-modules || (rm -rf ${DLDIR};return 1)
   else
    dnf ${DNF_OPT} --downloadonly --destdir=${DLDIR} reinstall kernel-module* kernel-modules
  fi;
  rpm --root=${1}/ --nodeps --noscripts -i --reinstall ${DLDIR}/kernel-module* && rm ${DLDIR}/kernel-module*
  kern_depmod ${1}
  rm -rf ${DLDIR}

  dnf ${DNF_OPT} --exclude kernel-module* reinstall kernel*
}

full_reinstall() {
  #reset locale-achive and timetamp
  rm ${WKDIR}/etc/timestamp ${WKDIR}/usr/lib/locale/locale-archive

  #rund update and check
  check_install ${WKDIR}

  #clean
  reinstall_clean ${1}

  #Reinstall all non alt/kernel packages
  reinstall_pkg

  #Reinstall alt packages
  reinstall_alt ${1}

  #Reinstall SSL CERTS
  reinstall_cacerts ${1}

  #Reinstall kernel
  reinstall_kern ${1}

  echo "Reinstall App/LSB"
  dnf ${DNF_OPT} reinstall legato lsb-release

  /sbin/ldconfig
}


check_install() {
  echo "Rebuild  DB"
  (rpm --root=${1}/ --rebuilddb && dnf ${DNF_OPT} clean all >/dev/null 2>&1) || return 1

  dnf_update ${1}/

  #Fix LIBC
  #rpm -e --justdb --nodeps ldd
  LDD_VER=$(dnf info ldd |awk '/Version/ {printf "%s",$3}')
  LIBC_VER=$(dnf info libc6 |awk '/Version/ {printf "%s",$3}')
  if [ "${LDD_VER}" != "${LIBC_VER}" ];then
    echo "Libc version out of date"
    dnf ${DNF_OPT} --allowerasing install libc6-${LDD_VER} ldconfig-${LDD_VER} libc6-utils-${LDD_VER}
    dnf ${DNF_OPT} reinstall dnf perl-module-config-heavy iptables-module-ip6t-eui64 iptables-module-xt-trace usb-modeswitch-data lsb-release base-files
    dnf ${DNF_OPT} install openssh-sftp-server
  fi;

  if ! dnf ${DNF_OPT} check --duplicates;then
    echo "Duplicates Found"
    fix_duoplicates ${1}
    kern_update ${1}
    dnf ${DNF_OPT} upgrade -b
    if ! dnf ${DNF_OPT} check --duplicates;then
     fix_duoplicates ${1}
     dnf ${DNF_OPT} upgrade -b
     if ! dnf ${DNF_OPT} check --duplicates;then
        fix_duoplicates ${1}
        dnf ${DNF_OPT} upgrade -b
      fi;
    fi;
  fi;

  #Fixup dependancies
  (dnf ${DNF_OPT} --allowerasing reinstall `dnf check |awk '/has missing requires/ {printf "%s ",$1}'` |awk -v RPM_DIR="--root=${1}/" '/not available/ {printf " rpm %s -e --justdb --nodeps %s\n",RPM_DIR,$3}' |sh) >/dev/null 2>&1
  (dnf ${DNF_OPT} --allowerasing reinstall `dnf check |awk '/has missing requires/ {printf "%s ",$1}'` |awk -v RPM_DIR="--root=${1}/" '/not available/ {printf " rpm %s -e --justdb --nodeps %s\n",RPM_DIR,$3}' |sh) >/dev/null 2>&1

  echo "Remove Package Groups/Update"
  dnf ${DNF_OPT} upgrade -b
  dnf ${DNF_OPT} --noautoremove erase packagegroup*
  dnf_update ${1}/

  echo "Reinstall Package Groups"
  (dnf ${DNF_OPT} install packagegroup-comb-dunfell && dnf ${DNF_OPT} --noautoremove erase packagegroup-comb-dunfell) || return 1
  dnf ${DNF_OPT} mark install ${MARK_PKG}

  /sbin/ldconfig
}

chroot_img() {
  if [ -b ${1} ];then
    MNTPNT=/mnt
  else
    MNTPNT=${1}
  fi;

  cp /etc/resolv.conf ${MNTPNT}/run/resolvconf
  if [ ! -e  ${MNTPNT}/etc/resolv.conf ];then
    ln -s /etc/resolvconf/run/resolv.conf ${MNTPNT}/etc/resolv.conf
  fi;
  if [ ! -d ${MNTPNT}/mnt/legato ];then
    mkdir -p ${MNTPNT}/mnt/legato
  fi;


  echo "export PS1='($(basename -s .img ${MNTPNT}))\u@\h:\w\\$ ';cd ~;rm .profile" > ${MNTPNT}/home/root/.profile
  echo "[ -x /usr/bin/ssh-agent ] && eval \`ssh-agent -k\`;dnf clean all;rm -f .profile .bash_logout .bash_history" > ${MNTPNT}/home/root/.bash_logout

  env -i TERM=${TERM} HOME=/home/root LANG=${LANG} /usr/sbin/chroot ${MNTPNT} /bin/bash -l
  for clean_root in .profile .bash_history .bash_logout;do
    if [ -e ${MNTPNT}/home/root/${clean_root} ];then
      rm ${MNTPNT}/home/root/${clean_root}
    fi;
  done;
}

bt_listen_pair() {
  if [ ! -d /sys/class/bluetooth/hci0 ] || [ -d /sys/class/net/bnep0 ];then
    return 1;
  fi;

  printf "* *\n" > /tmp/bt-pins
  chmod 400 /tmp/bt-pins

  bluetoothctl discoverable-timeout ${1}
  bluetoothctl discoverable on
  bluetoothctl agent off
  bt-agent -p /tmp/bt-pins -c DisplayOnly &

  bluetoothctl --timeout ${1} scan on

  kill  -9 `pidof bt-agent`
  rm /tmp/bt-pins
}

bt_select_net_device() {
  if [ ! -d /sys/class/bluetooth/hci0 ] || [ -d /sys/class/net/bnep0 ];then
    return 1;
  fi;

  if ! bluetoothctl info ${1} >/dev/null 2>&1;then
    return 1;
  fi;

  if [ "$(bluetoothctl info ${1} |awk '/Paired/ {printf "%s\n", $2}')" != "yes" ];then
    return 2
  fi;

  if [ ! -n "$(bluetoothctl info ${1} |awk '/UUID: NAP/')" ];then
    return 3
  fi;

  if [ "$(bluetoothctl info ${1} |awk '/Trusted/ {printf "%s\n", $2}')" != "yes" ];then
    sleep 5
    bluetoothctl trust ${1} >/dev/null 2>&1 || return 4
  fi;

  if [ "$(bluetoothctl info ${1} |awk '/Connected/ {printf "%s\n", $2}')" != "yes" ];then
    sleep 5
    bluetoothctl connect ${1} >/dev/null 2>&1 || return 5
  fi;

  if [ -n "$(bluetoothctl info ${1} |awk '/UUID: NAP/')" ];then
    if [ -e /var/run/udhcpc.bnep0.pid ];then
      kill `cat /var/run/udhcpc.bnep0.pid`
    fi;
    bt-network -d -c ${1} nap || return 6
  fi
}

bt_find_net_dev() {
  for device in $(bluetoothctl devices |awk '{printf "%s ",$2}');do
    bt_select_net_device ${device} && return 0
  done;
  return 1
}

## Got help
#mount_ns.sh
#mount_combo.sh
#flash_ns.sh
#lan_dnf.sh
#remote_dnf.sh
#board_load.sh
#lan_load.sh
#remote_load.sh
#board_connect.sh
#lan_connect.sh
#remote_connect.sh
#label_print

## Needs help
#board_reset.sh
#board_check.sh

## Interal
#env_setup.sh
#start_agent.sh
#stop_agent.sh
#wpnetlink
#common
#comb_bt

usage_help() {
cat <<__EOF_HELP__

$(basename ${0}) [OPTION [PATH]] | [PATH]

With no options supplied the system is updated should there be a duplicate file or dependancy is not met --fix will be executed.

if a path is supplied the image at that path will be updated if a image does not exist it will be created..

Help
----

-? | -h | --help
	Display this help information.
	Press q to quit.
	Press h to see more info on options.

Image files
-----------

<file>.img
	Created with --import-ns / --import-combo / --unpack.
	If only <file> is specified as option then it will be created from running system repository.

<file>.img.xz
	Compressed full image.
	created with --xz option <file>.img must exist to compress.

<file>.img.pack
	Packed image where the size is reduced to flash onto a system.
	a image file can be generated from this file by importing it using --unpack/--import-* options.
	created with --pack option <file>.img must exit to create it.

<file>.img.pack.xz
	Compressed packed image used that can be copied to a production system for flashing
	a image file can be generated from this file by importing it using --unpack/--import-* options.
	created with --xz-pack option.

<file>.tar.bz2
	Compresed tar file downloweded from the repository.
	created with --import-ns option

<file>.img.bz2
	Compresed wic file downloweded from the repository.
	created with --import-combo option

Path
----

The path is the path to the mount point where the file  <path>.img is mounted the full path must be given.
The default path <${DEF_IMG}> is specified using - as a path value.

Example (<PATH> = -)
path ${DEF_IMG} where file ${DEF_IMG}.img will be mounted.

If a path is specified and no image exists one will be created from the reposiory see the --import-* options.

--rpiboot/--rpiboot-chroot will use path ${DEF_IMG}-rpiboot

Update Options
--------------

It is best to use --chroot to execute these functions on a path if no path is supplied / is used.
If a path is supplied the image will be mounted and unmounted if not mounted.

--fix [path]
	Rebuild the rpm db incase its inconsistent.
	Update the system.
	Ensure the correct version of libc is installed.
	Resolve any duplicates.
	Resolve any missing dependancies.
	Reinstall all packagegroups to ensure any missing packages are installed.
	If the locale-archive config.txt cmdline.txt timestamp are missing they created

--reinstall [path]
	Remove locale-archive and timestamp to be recreated when --fix is executed below.
	Execute --fix see above
	Remove packages no longer used can be executed using --cleanup
	Reinstall all packages except for kernel, cacerts, app ,lsb_release and packages to keep alternates in sync
	Reinstall all packages neede4d to keep alternates in sync can be executed using --alt
	Reinstall ca certificates can be executed using --cacerts
	Reinstall kernel can be executed using --kern
	Reinstall lsb_release and app

--cleanup [path]
	Remove pulseaudio auto detect along with packages been obsoleted

--flash-boot
	For Combo boards write the tf-a/fip files to emmc

--alt [path]
	Reinstall packages with alternates in the correct order to match those generated by build system.
	If --diff outputs alternate files executing this will re sync them.

--cacerts [path]
	Update mozilla cacerts without using dnf as dnf requires cacerts.

--kern [path]
	Reinstall the currently installed kernel without using dnf to install the packages to speed up the install.

--mk-locale [path]
	Update the locale archive if needed see output of --diff

--install-prod [path]
	Install production tools (wpnetlink)

--uninstall-prod [path]
	Remove production tools (wpnetlink)

File Options
------------

If no path is supplied ${DEF_IMG} is used these functions apply to image files that should be un mounted first.

--xz [path]
	Create a compressed image file

--pack [path]
	Create a packed image to flash a new system.

--xz-pack [path]
	Create a compressed pack file it will update or create the pack file before compressing (--pack).

--unpack [path]
	Create a image from a packed image or compressed pack image.

--import-ns [path]
	Create a image file from a compressed tar file down loaded from repository.

--import-combo [path]
	Create a image file from a compressed wic file down loaded from repository.

Image Options
-------------

If no path is supplied - is used these functions apply to image files that should be un mounted first.
The image will be mounted and unmounted if not mounted running except for --mount / --umount.

--mount [path]
	Mount image this is not required unless you want to run multiple commands without unmounting.
	Do not execute --mount when executing file options.
	If a packed file is found and no image exists it is unpacked see --unpack.
	The image must be unmounted with --umount.

--chroot [path]
	Chroot into a mounted image this is the prefered way to execute update commands on a image.

--rpiboot [path]
	The path will have -rpiboot appended
	Do not plug in a device before this command is executed if wpnetlink is running.
	To perform functions on a physical device use this as a alternaive to --mount.
	If wpnetlink is running it will be stopped and restarted when --umount is run
	The device must be unmounted calling --rpiboot again.
	Only works with ns board.

--rpiboot-chroot [path]
	--chroot to a path mounted with --rpiboot or mount and unmount it on exit running --rpiboot

--umount [path]
	Unmount a image mounted with --mount

--diff [path]
	Compare the system to mounted filesystem.

Network Options
---------------

--bt-pair
	Enable pairing and/or connect to any paired bluetooth devices that we can tether to.

--bt-net
	Connect to any paired bluetooth devices that we can tether to.

*#2638
	Supercode to activate from keypad if the device is linked it runs --bt-net if unlinked --bt-pair

*#0020
	Supercode to display current IP address of the device

*#0007
	Supercode to display default gateway of device

__EOF_HELP__

rpm --quiet -q wpnetlink && cat <<__EOF_HELP__
Production tool Options
-----------------------

--wp-start
	Start the production service if stopped see --rpiboot/--rpiboot-chroot/--umount
	The service is started at boot.

--wp-stop
	Stop the production service if started see --rpiboot/--rpiboot-chroot/--umount

--wp-status
	Show status of the production tools.

Production tool scripts (wpnetlik)
----------------------------------

To start/stop the wpnetlink service.

/etc/init.d/wpnetlink <start | stop>

To set the SSH_KEY variable execute:
export SSH_KEY=<path to key file>

mount_ns.sh / mount_comb.sh
---------------------------

The path used is hardcoded to ~/${DEF_IMG_NAME}:${OPTDIR}/${ARCH_NAME}/${DEF_IMG_NAME}
The above path is the same as $(basename ${0}) default path.

If no options are specified it will execute --mount or --unmount depending on if image is mounted.
These tools are designed to be run on non native systems ie standard pi or linux pc.
chroot will only work on a native system.

--mount
	Similar to --mount above does not require a path.
	If a packed file is found and no image exists it is unpacked see --unpack.

--chroot
	Chroot into a mounted image this is the prefered way to execute update commands on a image.
	This requires it to be run on native CPU ie PI 3/4

--rpiboot
	The path used will have -rpiboot appended
	Do not plug in a device before this command is executed if wpnetlink is running.
	To perform functions on a physical device use this as a alternaive to --mount.
	If wpnetlink is running it will be stopped and restarted when unmounted
	The device must be unmounted calling --rpiboot again.
	Only works with ns board.

--rpiboot-chroot
	--chroot to a path mounted with --rpiboot or mount and unmount it on exit running --rpiboot

--umount
	Similar to --umount above does not require a path.

--xz
	Create a compressed image file.

--pack
	Create a packed image to flash a new system..

--xz-pack
	Create a compressed pack file it will update or create the pack file before compressing (--pack).

--import
	Create a image file from a compressed tar file down loaded from repository.

--expand
	Increase the image by 512MB

flash_ns.sh
-----------

This runs the flash subroutine from the command line this should not be done unless wpnetlink is stoped or the module is blocked.
A module will not be flashed twice in a row running this command even when wpnetlink is running will force it is flashed.
If you run it while wpnetlink is active its recommended to quit it before swaping modules.

wpnetlink will be stopped and started when running this script.
wpnetlink can be restarted running mount_ns.sh --umount

lan_dnf.sh <IP[:port]> / remote_dnf.sh <port>
---------------------------------------------

Execute dnf commands on a remote systems to run ${0} --fix via atd this is is needed on older boards or if the script fails.

dnf_lan.sh <IP[:port]>
	Run update on a NS board with the specified lan address default port 22

dnf_remote.sh <port>
	Run update on a NS board with remote ssh port.

board_load.sh [file] lan_load.sh [file] <ip[:port]>remote_load.sh file <port>
-----------------------------------------------------------------------------

Update a Lite board if file is specified it will be used otherwise default installed firmware will be loaded.

board_load.sh [file]
	Update a board connected on USB IP 192.168.2.2 port 22

lan_load.sh [file] <IP[:port]>
	Update a board on the network specifying IP address the default port is 22

remote_load.sh [file] <port>
	Update a board on the VPN specify the remote ssh port.


board_connect.sh lan_connect.sh <ip[:port]>remote_connect.sh >port>
-------------------------------------------------------------------

Update a Lite board

board_connect.sh
	Connect to a board connected on USB IP 192.168.2.2 port 22

lan_connect.sh <IP[:port]>
	Connect to a board on the network specifying IP address the default port is 22

remote_connect.sh <port>
	Conect to a board on the VPN specify the remote ssh port.


label_print [-p <printer ip>] <serial>[ <serial> ....]
------------------------------------------------------

Print one or more labels if PRINTER evn variable is set there
is no need to set the printer ip on the command line.

__EOF_HELP__
}

if [ "${2}" ] && [ "${2}" != "-" ];then
  IMG=${2-${DEF_IMG}}
 else
  IMG=${DEF_IMG}
fi

if [ "${1}" == "--help" ] || [ "${1}" == "-h" ] || [ "${1}" == "-?" ];then
  usage_help |less
  exit 0
 elif [ "${1}" == "--mount" ];then
  shift;
  mount_image ${IMG}
  exit 0;
 elif [ "${1}" == "--rpiboot" ];then
  shift;
  TMPDEV="${TMPDEV}-rpiboot"
  mount_ns_board ${IMG}-rpiboot
  exit 0;
 elif [ "${1}" == "--rpiboot-chroot" ];then
  shift;
  TMPDEV="${TMPDEV}-rpiboot"
  if [ ! -e ${TMPDEV} ];then
    mount_ns_board ${IMG}-rpiboot
    chroot_img ${IMG}-rpiboot
    mount_ns_board ${IMG}-rpiboot
   else
    chroot_img ${IMG}-rpiboot
  fi;
  exit 0;
 elif [ "${1}" == "--umount" ];then
  shift;
  umount_image ${IMG}
  exit 0;
 elif [ "${1}" == "--wp-status" ];then
  shift;
  if ! rpm --quiet -q wpnetlink;then
    echo "Production tools not installed"
    exit 1
  fi
  /etc/init.d/wpnetlink status || exit $?
  exit 0;
 elif [ "${1}" == "--wp-start" ];then
  shift;
  if ! rpm --quiet -q wpnetlink;then
    echo "Production tools not installed"
    exit 1
  fi
  if ! /etc/init.d/wpnetlink status;then
    /etc/init.d/wpnetlink start
  fi
  exit 0;
 elif [ "${1}" == "--wp-stop" ];then
  shift;
  if ! rpm --quiet -q wpnetlink;then
    echo "Production tools not installed"
    exit 1
  fi
  if /etc/init.d/wpnetlink status;then
    /etc/init.d/wpnetlink stop
    if /etc/init.d/wpnetlink status > /dev/null 2>&1;then
      killall -9 wpnetlink
    fi;
    /etc/init.d/wpnetlink status
  fi
  exit 0;
 elif [ "${1}" == "--chroot" ];then
  shift;
  if [ ! -e ${TMPDEV} ] && [ ! -b ${IMG} ];then
    mount_image ${IMG}
    chroot_img ${IMG}
    umount_image ${IMG}
   elif [ -b ${IMG} ] && [ ! -e /mnt/etc ];then
    mount_image ${IMG}
    chroot_img ${IMG}
    umount_image ${IMG}
   else
    chroot_img ${IMG}
  fi;
  exit 0;
 elif [ "${1}" == "--unpack" ];then
  shift;
  unpack_ns_img ${IMG} || exit 1
  exit 0
 elif [ "${1}" == "--pack" ];then
  shift;
  pack_ns_img ${IMG} || exit 1
  exit 0
 elif [ "${1}" == "--xz-pack" ];then
  shift;
  pack_ns_img ${IMG} || exit 1
  xz_pack_ns_img ${IMG} || exit 1
  exit 0
 elif [ "${1}" == "--import-ns" ];then
  shift;
  if [ ! "${1}" ];then
    if [ -d ${OPTDIR} ];then
      IMG=${OPTDIR}/${ARCH_NAME_NS}/comb-ns
     else
      IMG=~/comb-ns
    fi;
  fi;
  create_ns_image ${IMG}
  exit 0
 elif [ "${1}" == "--import-combo" ];then
  shift;
  if [ ! "${1}" ];then
    if [ -d ${OPTDIR} ];then
      IMG=${OPTDIR}/${ARCH_NAME_COMBO}/comb-combo
     else
      IMG=~/comb-combo
    fi;
  fi;
  create_combo_image ${IMG}
  exit 0
 elif [ "${1}" == "--diff" ];then
  shift;
  if [ ! -e ${TMPDEV} ];then
    mount_image ${IMG}
    diff_image ${IMG}
    umount_image ${IMG}
   else
    diff_image ${IMG}
  fi;
  exit 0
 elif [ "${1}" == "--fix" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  check_install ${WKDIR}
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  if [ ! "${WKDIR}" ] && [ -e /run/initctl ];then
    /sbin/reboot
  fi
  exit 0;
 elif [ "${1}" == "--reinstall" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  full_reinstall ${WKDIR}
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  if [ ! "${WKDIR}" ] && [ -e /run/initctl ];then
    /sbin/reboot
  fi
  exit 0;
 elif [ "${1}" == "--flash-boot" ];then
  shift;
  combo_flash_boot || exit 1
  exit 0
 elif [ "${1}" == "--cleanup" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  reinstall_clean ${wkdir} || exit 1
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--cacerts" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  reinstall_cacerts ${wkdir} || exit 1
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--alt" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  reinstall_alt ${wkdir} || exit 1
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--kern" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y -q --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
  else
    DNF_OPT="-y -q"
    WKDIR=""
  fi;
  reinstall_kern ${WKDIR} || exit 1
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--mk-locale" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
   else
    WKDIR=""
  fi;
  rm ${WKDIR}/usr/lib/locale/locale-archive
  mk_locale ${WKDIR}
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--install-prod" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
   else
    DNF_OPT="-y"
    WKDIR=""
  fi;
  if ! rpm --quiet -q wpnetlink;then
    dnf ${DNF_OPT} install packagegroup-comb-prod
   else
    echo "Already installed"
  fi;
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--uninstall-prod" ];then
  shift;
  if [ "${1}" ] && [ -d ${IMG} ];then
    DNF_OPT="-y --installroot=${IMG}"
    WKDIR="${IMG}"
    if [ ! -e ${TMPDEV} ];then
      mount_image ${IMG}
      UMT_FLAG=1
    fi;
   else
    DNF_OPT="-y"
    WKDIR=""
  fi;
  if ! rpm --quiet -q wpnetlink;then
    echo "Not installed"
   else
    dnf ${DNF_OPT} erase packagegroup-comb-prod
  fi;
  if [ "${UMT_FLAG}" == "1" ] && [ -e ${TMPDEV} ];then
    umount_image ${IMG}
  fi
  exit 0
 elif [ "${1}" == "--xz" ];then
  shift;
  if [ -e ${IMG}.img ];then
    if [ -e "${IMG}.img.xz" ];then
      rm ${IMG}.img.xz
    fi;
    xz -T 0 -k --verbose ${IMG}.img
  fi;
  exit 0
 elif [ "${1}" == "--bt-pair" ];then
  shift;
  if ! bt_find_net_dev;then
    bt_listen_pair 60
    bt_find_net_dev
  fi;
  exit 0
 elif [ "${1}" == "--bt-net" ];then
  shift;
  bt_find_net_dev
  exit 0
fi;

if [ "${1}" ];then
  if [ "${1}" == "-" ];then
    IMG=${DEF_IMG}
   elif [ "${1:0:1}" ==  "-" ];then
    echo "Not creating image ${1}"
    exit 0;
  fi
  install_root ${1}
 elif ! dnf check;then
  DNF_OPT="-y -q"
  check_install
  if [ -e /run/initctl ];then
    /sbin/reboot
  fi
  exit 0;
 else
  DNF_OPT="-y -q"
  dnf_update
fi;
