#!/bin/bash
#(c) Copyright Barry Kauler, Feb. 2015. License GPL3 (usr/share/doc/legal)
#see also 7build-live-cd in woofQ, /usr/sbin/savesession
#called via "install" icon on desktop.
#151202 complete rewrite. 151209 fix.
#160418 update messages, live-cd can now boot on uefi pcs.
#160419 remove the install-to-livecd frame.
#180408 support nvme drives.

export TEXTDOMAIN=installquirky
export OUTPUT_CHARSET=UTF-8

#150322 must run as root:
ME="`whoami`"
if [ "$ME" != "root" ];then
 echo "Must run as root user. Aborting."
 xmessage -bg '#FF8080' -center "Sorry, must run this application as 'root' user."
 exit 1
fi

#150320 detect if running inside a self-extracted archive:
WDcurrent="`pwd`"
PRE=''
TEXTDOMAINDIR='/usr/share/locale' #150422
if [ -f ${WDcurrent}/DISTRO_SPECS ];then
 . ${WDcurrent}/DISTRO_SPECS
 if [ -f ${WDcurrent}/gtkdialog ];then
  PRE="${WDcurrent}/"
  TEXTDOMAINDIR="${WDcurrent}/locale" #150422
 fi
else
 . /etc/DISTRO_SPECS
fi
export TEXTDOMAINDIR #150422

#150416 must run in correct arch:
#150930 neo64 has 64-bit kernel, 32-bit apps, get HOST_ARCH from /etc/DISTRO_SPECS...
if [ "$PRE" ];then
 if [ ! -f /etc/DISTRO_SPECS ];then
  HOST_ARCH="$(uname -m)"
  [ "$HOST_ARCH" ] || exit 1
 else
  HOST_ARCH="$(grep '^DISTRO_TARGETARCH' /etc/DISTRO_SPECS | cut -f 2 -d "'")"
 fi
 case $HOST_ARCH in
  x86_64|amd64) HOST_ARCH=amd64 ;; #151006
  *)      HOST_ARCH=x86   ;;
 esac
 if [ "$HOST_ARCH" != "$DISTRO_TARGETARCH" ];then
  echo "ERROR: The host Linux OS must have architecture '${DISTRO_TARGETARCH}'. Please download the correct Quirky Installer. Aborting."
  xmessage -bg '#FF6060' "ERROR: The host Linux OS must have architecture '${DISTRO_TARGETARCH}'. Please download the correct Quirky Installer. Aborting."
  exit 1
 fi
fi

CR='
'

#151004
if [ "$PRE" ];then
 LIBLZMA="$(find ${PRE} -mindepth 1 -maxdepth 1 -type f -name 'liblzma.so.*' | head -n 1)"
 LIBF2FS="$(find ${PRE} -mindepth 1 -maxdepth 1 -type f -name 'libf2fs.so.*' | head -n 1)"
 LIBUUID="$(find ${PRE} -mindepth 1 -maxdepth 1 -type f -name 'libuuid.so.*' | head -n 1)"
 export LD_PRELOAD="${LIBLZMA} ${LIBF2FS} ${LIBUUID}"
fi

#150320 do some sanity checks:
#151007 ldd will give stderr if glibc too old, ex: ./cp: /lib/libc.so.6: version `GLIBC_2.17' not found (required by ./cp) (got this with precise 5.7.1)
errTITLE="$(gettext 'Quirky Installer: error')"
RXVTEXE=''; errMSG=''
[ `which urxvt` ] && RXVTEXE='urxvt'
[ ! "$RXVTEXE" ] && [ `which rxvt` ] && RXVTEXE='rxvt'
[ ! "$RXVTEXE" ] && [ `which xterm` ] && RXVTEXE='xterm'
[ ! "$RXVTEXE" ] && errMSG="${errMSG}${CR}$(gettext "There is no 'urxvt', 'rxvt', or 'xterm' utility.")"
[ `which wget` ] || errMSG="${errMSG}${CR}$(gettext "There is no 'wget' utility.")"
[ `which xwininfo` ] || errMSG="${errMSG}${CR}$(gettext "There is no 'xwininfo' utility, needed by 'popup'.")" #150407
echo -n "" > /tmp/installquirky-ldd-err #151007
if [ "$PRE" ];then
 if [ ! `which ldd` ];then
  errMSG="${errMSG}${CR}$(gettext "The 'ldd' utility is missing.")"
 else
  #check bins work:
  mLDD=''
  for ABIN in cp gdisk gtkdialog mksquashfs popup syslinux unsquashfs vercmp
  do
   aLDD="$(ldd ${PRE}${ABIN} 2>/tmp/installquirky-ldd-err | ${PRE}busybox grep 'not found' | ${PRE}busybox tr -s '\t' ' ' | ${PRE}busybox tr -s ' ' | ${PRE}busybox cut -f 2 -d ' ')"
   [ -s /tmp/installquirky-ldd-err ] && break #151007
   [ "$aLDD" ] && mLDD="${mLDD}${CR}${aLDD}"
  done
  if [ "$mLDD" ];then
   xmLDD="$(${PRE}busybox echo -n "$mLDD" | ${PRE}busybox sort -u | ${PRE}busybox tr '\n' ' ')"
   errMSG="${errMSG}${CR}$(gettext 'These needed libraries are missing:')${CR}${xmLDD}"
  fi
 fi
fi
if [ -s /tmp/installquirky-ldd-err ];then #151007
 errMSG="$(gettext 'Error message:')${CR}`cat /tmp/installquirky-ldd-err`${CR}${CR}$(gettext 'The version of Linux currently running is too old or wrong architecture. Aborting.')"
 ${PRE}popup "level=top background=#FF8080 terminate=ok|<b>${errTITLE}</b>${CR}${errMSG}"
 exit 1
fi
if [ "$errMSG" ];then
 ${PRE}popup "level=top background=#FF8080 terminate=ok|<b>${errTITLE}</b>${errMSG}"
 exit 1
fi
export RXVTEXE

#find non-usb drives (code from rc.sysinit, also refer /etc/rc.d/PUPSTATE). 150327 180408
ALLDRVS0="`${PRE}busybox find /sys/block -maxdepth 1 -name 'mmc*' -o -name 'sd*' -o -name 'sr*' -o -name 'nvme*' | ${PRE}busybox xargs readlink 2>/dev/null | ${PRE}busybox grep -v '/usb[0-9]' | ${PRE}busybox rev | ${PRE}busybox cut -f 1 -d '/' | ${PRE}busybox rev`" #all *except* usb!
ALLDRVS="`${PRE}busybox echo "$ALLDRVS0" | ${PRE}busybox tr '\n' ' '`" #all *except* usb!
[ "$ALLDRVS" = " " ] && ALLDRVS=""
ATADRIVES="`${PRE}busybox echo "$ALLDRVS0" | ${PRE}busybox grep -v '^sr' | ${PRE}busybox tr '\n' ' '`"
[ "$ATADRIVES" = " " ] && ATADRIVES=""
ATAOPTICALDRIVES="`${PRE}busybox echo "$ALLDRVS0" | ${PRE}busybox grep '^sr' | tr '\n' ' '`"
[ "$ATAOPTICALDRIVES" = " " ] && ATAOPTICALDRIVES=""
export ATADRIVES #needed by probepart (when run in self-extracting archive)


###########frontend window###############
HELPICON="gtk-index"
M_close="$(gettext 'Close')"
H_part="$(gettext 'A drive may be divided up into partitions. MSDOS and Windows, however, refer to drive A:, B: etc., but these are actually partitions within the drive. Linux names a drive with letters, for example sda, and partitions within that drive as sda1, sda2, etc.')${CR}${CR}<b>$(gettext 'Full installation')</b>${CR}$(gettext 'A full installation to a partition is the conventional mode in which Linux is installed. It requires the entire partition, and the filesystem must be a Linux type, that is, <b>ext2</b>, <b>ext3</b>, <b>ext4</b>, <b>reiserfs</b>, or <b>f2fsf</b>. It also must be large enough for anticipated usage, at least 8GB.')${CR}$(gettext 'The Quirky Installer does not create the partition, nor filesystem, it must already exist.')${CR} <span fgcolor='#FF0000'><b>$(gettext 'Any files currently in the partition will be erased')</b></span>${CR}${CR}<b>$(gettext 'Frugal installation')</b>${CR}$(gettext 'The most important feature of this mode of installation is that it resides without disturbing whatever is already in the partition. A frugal installation is just a folder with a few files in it.')${CR}$(gettext 'Another feature is that the filesystem may be any type, Linux, or <b>msdos</b>, <b>vfat</b>, or <b>ntfs</b>. The latter are filesystems used by Windows installations.')${CR}$(gettext 'However, a frugal install has limitations. The main one is that eveything runs in RAM, and this restricts how many packages can be installed. etc.')${CR}$(gettext 'Note that as everything runs in RAM, operation is very fast.')"
export DLG_HELP_PART="<window resizable=\"false\" title=\"$(gettext 'Help: Partition')\" icon-name=\"${HELPICON}\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${H_part}\"</label><variable>DLG_HELP_PART</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP_PART</action></button></hbox></vbox></window>"
H_drv="$(gettext 'A drive may be divided up into partitions. MSDOS and Windows, however, refer to drive <b>A:</b>, <b>B:</b> etc., but these are actually partitions within the drive. Linux names a drive with letters, for example <b>sda</b>, and partitions within that drive as <b>sda1</b>, <b>sda2</b>, etc.')${CR}$(gettext 'Installing Quirky to an entire drive means that any existing partitions will be erased, and Quirky will create new partitions.')${CR}${CR}$(gettext 'This mode of installation is usually to removable drives, such as USB Flash stick and SD-card. A drive of at least 8GB is required.')${CR}${CR}<b>Full installation</b>${CR}$(gettext 'A full installation is the conventional mode in which Linux is installed. The Installer will create a partition on the drive, with a Linux filesystem.')${CR}${CR}<b>Frugal installation</b>${CR}$(gettext 'As above, the entire drive is erased and new partitions created. However, a frugal install is just a folder with a few files in it. A frugal install has limitations, the most important being that everything runs in RAM. However, that also means performance is very fast.')${CR}${CR}<b>$(gettext 'Booting')</b>${CR}$(gettext 'The Quirky Installer will make the drive <b>bootable</b>. This means you do not have to install any boot manager yourself, such as GRUB. You will, however, need to setup the <b>BIOS/UEFI firmware</b> to recognise and boot from the external drive, if plugged in -- this is explained further in the next window.')"
export DLG_HELP_DRV="<window resizable=\"false\" title=\"$(gettext 'Help: Drive')\" icon-name=\"${HELPICON}\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${H_drv}\"</label><variable>DLG_HELP_DRV</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP_DRV</action></button></hbox></vbox></window>"

H_livecd="$(gettext 'Quirky is available online as an <b>ISO</b> file, which may be downloaded, burnt to CD, and becomes a <b>live-CD</b>.')${CR}${CR}$(gettext 'The live-CD is suitable for evaluation of Quirky. The main disadvantage is that everything runs in RAM, severely limiting what can be downloaded and installed. However, this also means very quick performance. Effectively, a live-CD runs the same as a <b>frugal</b> installation -- in fact, a session can be saved in exactly the same way as a frugal installation.')${CR}${CR}$(gettext 'The live-CD can be booted on PCs with BIOS or UEFI firmware. All PCs manufactured prior to 2012 have BIOS-firmware. For PCs with UEFI firmware, the UEFI-Setup needs to have <b>Secure Boot</b> disabled. <b>Legacy Boot</b> does <i>not</i> have to be enabled. This is explained further in the next window.')${CR}${CR}<b>$(gettext 'USB "live-CD"')</b>${CR}$(gettext 'The ISO file may be written to a USB Flash stick, and it will bootup just as though it is a live-CD. To get started with Quirky, this is the way to go if you do not have an optical drive in your PC.')${CR}$(gettext 'Note though, for ongoing usage booting from a USB Flash stick, it is very much preferred to do a full install to the stick (or SD-card).')"
export DLG_HELP_LIVECD="<window resizable=\"false\" title=\"$(gettext 'Help: Live-CD')\" icon-name=\"${HELPICON}\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${H_livecd}\"</label><variable>DLG_HELP_LIVECD</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP_LIVECD</action></button></hbox></vbox></window>"

#160419 removed...
# <frame $(gettext 'Live-CD')>
#  <text><label>$(gettext 'This option installs Quirky to a CD (or DVD), which may be booted. This is known as a live-CD.')</label></text>
#  <hbox><button><label>$(gettext "INSTALL")</label><action type=\"exit\">installlivecd</action></button><button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP_LIVECD</action></button></hbox>
# </frame>
 
export IQ_DLG1="<window title=\"$(gettext "Quirky Installer")\" icon-name=\"gtk-convert\">
<vbox>
 <text use-markup=\"true\"><label>\"<b>$(gettext 'Welcome to the Quirky Installer!')</b>\"</label></text>
 <text><label>$(gettext 'Please choose one of the following options:')</label></text>
 
 <frame $(gettext 'Partition')>
  <text use-markup=\"true\"><label>\"<b><span fgcolor='#FF0000'>$(gettext 'You need to install a Boot Manager, such as GRUB, which is not done by the Quirky Installer')</span></b>\"</label></text>
  <text><label>$(gettext 'Install to a partition in a hard drive. Usually this is a fixed internal drive, and the partition size should be at least 8GB.')</label></text>
  <radiobutton><label>$(gettext 'Full installation')</label><variable>CHK_PART_FULL</variable></radiobutton>
  <radiobutton><label>$(gettext 'Frugal installation')</label><variable>CHK_PART_FRUGAL</variable></radiobutton>
  <hbox>
   <button><label>$(gettext "INSTALL")</label><action type=\"exit\">installpartition</action></button>
   <vbox><button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP_PART</action></button></vbox>
  </hbox>
 </frame>
 
 <frame $(gettext 'Drive')>
  <text><label>$(gettext 'Install to an entire drive. Usually this is a removable drive, such as USB Flash stick or SD-card. A drive of at least 8GB is required.')</label></text>
  <radiobutton><label>$(gettext 'Full installation')</label><variable>CHK_DRV_FULL</variable></radiobutton>
  <radiobutton><label>$(gettext 'Frugal installation')</label><variable>CHK_DRV_FRUGAL</variable></radiobutton>
  <hbox>
   <button><label>$(gettext "INSTALL")</label><action type=\"exit\">installdrive</action></button>
   <vbox><button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP_DRV</action></button></vbox>
  </hbox>
 </frame>
 
 <hbox>
  <button cancel></button>
 </hbox>
</vbox>
</window>"
RETSTRING1="$(${PRE}gtkdialog --program=IQ_DLG1 --center)"
[ $? -ne 0 ] && exit
eval "$RETSTRING1"
[ "${EXIT:0:7}" != "install" ] && exit

###############do it#############
  if [ "$PRE" ];then
   PRE2="$PRE"
  else
   PRE2="/usr/local/install_quirky/"
  fi
  case "$EXIT" in
   ##########################################################################
   installdrive)
    if [ "$CHK_DRV_FULL" == "true" ];then
     ${PRE2}install-quirky-to-drive
    else
     ${PRE2}install-quirky-to-drive frugal #passed param "frugal"
    fi
   ;;
   ##########################################################################
   installpartition)
    if [ "$CHK_PART_FULL" == "true" ];then
     ${PRE2}install-quirky-to-partition
    else
     ${PRE2}install-quirky-to-frugal
    fi
   ;;
   ##########################################################################
   installlivecd) #150402
    ${PRE2}install-quirky-to-cd
   ;;
   *)
    exit
   ;;
  esac

###END###
