#!/bin/sh
# grub4dosconfig
#2018-09-18 v1.9.4: merge woof, fix chain loading grub2, always install wee as for mbr, fix for full installed (mavrothal)
# grub2config
#2021-08-12 v2.0: grub2 for uefi
#2021-08-20 v2.0.1: was missing nls, remove pdrv option, downgrade grub to 2.0.2
#2024-03-25 v2.0.2: add SPLASH image and icon (josejp2424, nilsonmorales) ; parse drives with parted (rather than fdisk) and fix failed NVME/eMMC/GPT partition detection (wizard)
#2024-08-27 v2.0.8: graphical boot menu layout, ucode.cpio support, drive icon, launch gparted, proceed without 'boot' flag
#2024-09-05 v2.0.9: gtk2dialog, without guess_fstype
#2024-09-15 v2.1:	mbr stuff ext4 support no need wee nor grub4dos, pdrv option, check target space, refresh_drive_icons,
#2024-09-24 v2.1.1:	RAM mode entry, sort detected os, background2 for removable devices
MYVERSION=2.1.1

APPNAME=$(basename "$0")
APP=$(readlink -e $0)
[ "$APP" ] || APP=$0
APPDIR=$(dirname "$APP")
[ "$APPDIR" = "." ] && APPDIR=$(pwd)
MYPREFIX=$(dirname "$APPDIR")
APPTMP=/tmp/$APPNAME
mkdir -p $APPTMP
MYLOG=$APPTMP/$APPNAME.log
MYLOG2=$APPTMP/$APPNAME.err
COUNTFILE=$APPTMP/$APPNAME.count
echo "$0 $@" > $MYLOG
echo "version $MYVERSION" >>  $MYLOG
date  >>  $MYLOG
CREDIT="$APPNAME $MYVERSION"
DEBUGFLAG=""

case $1 in
	*-d*) DEBUGFLAG="yes"; shift;;
	*-*) echo $CREDIT; exit;;
esac
PARAM1=$1

tty | grep -q '^/dev/' && DEBUGFLAG="yes"

debug() {
	[ "$DEBUGFLAG" != "yes" ] && return
	echo "$@" >&2
	echo "$@" >> $MYLOG
} 

# default options
GRUB_PUPPY_DEPTH=2	;# 2 :top subfolder, 3 :one more deeper level
GRUB_PUPPY_ADDOPTION_DEFAULT="pfix=fsck"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
SAFEOPTIONS="pfix=ram,nox nosmp noapic i915.modeset=0 radeon.modeset=0 nouveau.modeset=0"	#v1.9 removed 'nodma nopcmcia'#v1.9.1: removed 'acpi=off apm=off', add modeset
GRUB_DEFAULT=0	;# item number count from 0
GRUB_TIMEOUT=10	;# seconds
for D in "$MYPREFIX/" "/" "$TOPDIR/"; do
	F=${D}etc/default/grub
	[ -s "$F" ] && source "$F" && break
done
PUPPYOPTIONS="$GRUB_PUPPY_ADDOPTION_DEFAULT"
LINUXOPTIONS="$GRUB_CMDLINE_LINUX_DEFAULT"
PUPPY_DEPTH=$GRUB_PUPPY_DEPTH
[ $PUPPY_DEPTH -gt 0 ]  || PUPPY_DEPTH=1
GRUB_FONT="DejaVuSansMono18.pf2"

SPLASHPATH="$MYPREFIX/share/grub2config/theme"			#/splash.xpm	#v1.7.9 note: 'splash.xpm' must be 640x480, 14 colors
ANOTHER_BACKGROUND="$MYPREFIX/share/grub2config/background2.png"		#2.1.1 another background for removable devices
BACKGROUND_PATH=/theme/puppy/background.png

#grub stuff size
BSIZE_MBR=100	;# x512byte
KSIZE_MBR=4400	;# kB
KSIZE_UEFI=6000
THEME="/usr/share/grub2config/theme"
KSIZE_THEME=$(du -k -s "$THEME" | tr -dc '0-9')
[ "$KSIZE_THEME" ] || KSIZE_THEME=0

export TEXTDOMAIN=grub2config
export TEXTDOMAINDIR=/usr/share/locale
export OUTPUT_CHARSET=UTF-8
LOCALE="$MYPREFIX/share/locale"
[ -d "$LOCALE" ] && TEXTDOMAINDIR="$LOCALE"
#debug "TEXTDOMAINDIR=$TEXTDOMAINDIR"

APPLIBDIR=/usr/lib/grub2config
D="$MYPREFIX/lib/grub2config"
[ -d "$D" ] && APPLIBDIR="$D"

_OK=$(gettext "OK")
_Help=$(gettext "Help")
_Probing=$(gettext "Searching.")
_Quit=$(gettext "Click 'OK' to quit this program.")
_Anyway=$(gettext "Do it anyway")
_Unsure=$(gettext "Click 'Cancel' here, if you are unsure.")
_Missings=$(gettext "Missings")

#-- simple localization for scripts by Shinobar based on MU. 
# set locale
for lng in C $(echo $LANGUAGE|cut -d':' -f1) $LC_ALL $LANG;do :;done   # ex.    ja_JP.UTF-8
# search locale file
lng1=$(echo $lng|cut -d'.' -f1)      # ex.   ja_JP
lng2=$(echo $lng|cut -d'_' -f1)   # ex.   ja

LOCAL_HELP=grub2config_help.html
APPDOCDIR=/usr/share/doc/grub2config
D=$MYPREFIX/share/doc/grub2config
[ -d "$D" ] && APPDOCDIR="$D"
H="$APPDOCDIR/$LOCAL_HELP"
for D in $lng $lng1 $lng2 C en
do
	F="$APPDOCDIR/$D/$LOCAL_HELP"
	[ -f "$F" ] && H="$F" && break
done
LOCAL_HELP="$H"

# help handler
HTMLVIEWERS="$BROWSER defaulthtmlviewer defaultbrowser dillo seamonkey mozilla firefox opera"
HELPVIEWER=""
for PROG in $HTMLVIEWERS;do
	which $PROG >/dev/null && HELPVIEWER=$PROG && break
done
ICONS="/usr/local/lib/X11/mini-icons"
ICONS="/usr/local/lib/X11/mini-icons"
SVGICONS="/usr/share/pixmaps/puppy"
CLOCK_PIX="<input file>$ICONS/mini-clock.xpm</input>"
[ -s "$SVGICONS/clock.svg" ] && CLOCK_PIX="<input file>$SVGICONS/clock.svg</input><width>36</width>"
GPARTED_ICON=/usr/share/icons/hicolor/24x24/apps/gparted.png
INPUT_ICON=""
[ -s "$GPARTED_ICON" ] && INPUT_ICON="<input file>$GPARTED_ICON</input><width>32</width>"
GPARTED_LAUNCHER="<button tooltip-text=\"$(gettext 'Launch GParted')\">$INPUT_ICON<label>GParted</label><action>EXIT:Launch</action></button>"

percent()
{
	N=$1
	[ "$N" ] || N=0
	echo $N > $COUNTFILE 2>/dev/null
}
splash() {
	debug "splash $*"
  rm -f $COUNTFILE
  [ "$XPID" != "" ] && kill $XPID >/dev/null 2>&1
  XPID=""
  case "$1" in
  start|progress) ;;
  *) return ;;
  esac
	[ "$LC_ALL" = 'C' ] && LC_ALL="$LC_ALL_SAVE"
  PBAR=""
  if [ "$1" = "progress" ]; then
    echo "0" > $COUNTFILE
    PBAR="<progressbar>
      <input>while [ -f $COUNTFILE ]; do tail -n 1 $COUNTFILE 2>/dev/null; sleep 1; done; echo 100</input>
       <action>rm -f $COUNTFILE</action>
     </progressbar>"
  fi
  shift	# remove $1
  S=$(gettext "Wait a moment ...")
  DIALOG="<window title=\"$TITLE\"><vbox>
  <hbox>
  <pixmap>$CLOCK_PIX</pixmap>
  <text><input>echo -e -n \"$* $S\"</input></text>
  </hbox>
  $PBAR
  </vbox></window>"
  $GTKDIALOG -p DIALOG  -c >/dev/null &
  XPID=$!
  #LANG=C	# to be faster
}

probing() {
	splash "$1" "$_Probing"
}

WHERETO_FRAME=""
quit() {
	umountmine
	exit
}
fatal() {
	[ "$LC_ALL" = 'C' ] && LC_ALL="$LC_ALL_SAVE"
	local MSG="$1"
	local MSG2="$2"
	[ "$MSG" ] || MSG=$(gettext "Somewhat error occured.")
	[ "$MSG2" ] || MSG2="$(gettext "Click 'Cancel' to quit.")"
	echo -e "$MSG" >> $MYLOG
	DIALOG="<window title=\"$CREDIT - Error\"><vbox>
	$WHERETO_FRAME
   <hbox>
   <pixmap icon_size=\"6\">
    <input file stock=\"gtk-dialog-error\"></input>
   </pixmap>
 <text><label>\"$MSG\"</label></text>
 </hbox>
 <button><label>See $MYLOG</label>
   <action>defaulttextviewer $MYLOG &</action></button>
  <text><label>\"$MSG2\"</label></text>
  <hbox>
   "$(make_help_button "$HELP_SECTION")"
   <button cancel></button>
  </hbox>
  </vbox></window>"
  splash end
	$GTKDIALOG -p DIALOG -c &>/dev/null
	quit 
}

warning() {
	[ "$LC_ALL" = 'C' ] && LC_ALL="$LC_ALL_SAVE"
	local MSG="$1"
	local MSG2="$2"
	local BUTTON="$3"
	[ "$MSG" ] || MSG=$(gettext "Somewhat error occured.")
	[ "$MSG2" ] || MSG2="$_Unsure"
	echo -e "$MSG" >> $MYLOG
	DIALOG="<window title=\"$CREDIT\"><vbox>
	$WHERETO_FRAME
<frame Warning>
   <hbox>
     <pixmap icon_size=\"6\">
       <input file stock=\"gtk-dialog-warning\"></input>
     </pixmap>
     <text><input>echo -en \"$MSG\"</input></text>
   </hbox>
  </frame>
  <text><input>echo -en \"$MSG2\"</input></text>
  <hbox>
    "$(make_help_button "$HELP_SECTION")"
   $BUTTON<button tooltip-text=\"$_Anyway\"><input file stock=\"gtk-ok\"></input><label>\"$_OK\"</label><action>EXIT:OK</action></button>
   <button cancel></button>
  </hbox>
  </vbox></window>"
		probing end
		RET=$($GTKDIALOG -p DIALOG -c | grep -E '^[A-Z]*=')
		eval "$RET"
		[ "$EXIT" = "OK" ] && return
		local myDEV=$DRIVE
		echo $myDEV | grep -q '/' || myDEV="/dev/$myDEV"
		umount_all $myDEV
		[ "$EXIT" = "Launch" ] || quit
		debug "Llaunching gparted $myDEV"
		(gparted $myDEV)
		exec $0 $DRIVE
}

error_missing() {
	local myFATAL=""
	case "$1" in
		*-fatal) shift; myFATAL="yes";;
	esac
	local myMSG="$_Missings:$1"
	#local myMSG2="$2"
	[ "$myFATAL" ] && fatal "$myMSG" "$2"
	warning "$myMSG" "$2"
}

make_help_button() {
	[ "$LOCAL_HELP" ] || return
	SECTION=$1
	[ "$SECTION" ] && SECTION='#'$SECTION
	cat <<EOF
	<button  space-expand="false" space-fill="false"  tooltip-text="'${_Help}'"><input file stock="gtk-help"></input><action>'${HELPVIEWER}' file://'${LOCAL_HELP}${SECTION}' &</action></button>
	<text space-expand="true" space-fill="true"><label>"    "</label></text>
EOF
}

umountmine() {
	[ "$SMOUNTED" != "" ] && mount |grep -q " $SMOUNTED " && umount $SMOUNTED && SMOUNTED=""
}
umount_all() {
	local DRIVE=$1
	echo $DRIVE | grep -q '/' || DRIVE="/dev/$DRIVE"
	umountmine
	local PARTS=$(probepart | grep "^$DRIVE" | cut -d'|' -f1)
	local PART
	for PART in $PARTS; do
		umount $PART
	done
}
mountpoint() {
	PART=$(echo $1|cut -d '|' -f 1|cut -d '/' -f 3)
	FS=$(echo $1|cut -d '|' -f 2)
	umountmine
	MP=$(mount | grep "^/dev/$PART[ ]" | head -n 1 | cut -d ' ' -f 3)
	if [ "$MP" = "" ]; then
		MP="/mnt/$PART"
		mount | grep -q " $MP " &&  umount "$MP"
		[ -d "$MP" ] || mkdir -p "$MP"
		OPT=""
		[ "$FS" = "vfat" ] && OPT='-o iocharset=utf8'
		mount -t $FS $OPT /dev/$PART "$MP" >>  $MYLOG 2>&1 && SMOUNTED="$MP" || MP=""
		[ "$MP" = "" ] && return 1
	fi
	#echo $MP
	return 0
}

kbyte_free() {
	ALINE=$(df -k $1| grep -m 1 '/dev/')
	KFREE=$(echo $ALINE| cut -f4 -d' '| tr -dc '0-9')
	[ "$KFREE" ] || KFREE=0
	echo $KFREE
}

read_distro_name() {
	DNAME=$(distro_name "$@")
	echo $DNAME | grep -qi 'PUPPY_[a-zA-Z]' && DNAME=$(echo $DNAME | sed -e 's/PUPPY_//i')
	echo $DNAME | trim | tr ' ' '_' 
}
lookup_release() {
	F=$TOPDIR/etc/lsb-release
	[ -s "$F" ] && DNAME=$(grep -m1 'DISTRIB_DESCRIPTION=' $F| cut -f2 -d'=' | tr -d "'" | tr -d '"')  && return
	F=$TOPDIR/etc/os-release
	[ -s "$F" ] && DNAME=$(grep -m1 'PRETTY_NAME=' $F| cut -f2 -d'=' | tr -d "'" | tr -d '"')  && return
	F=$TOPDIR/etc/vine-release
	[ -s "$F" ] && DNAME=$(head -n 1 $F)
}
distro_name() {
	TOPDIR=$1
	DNAME=""
	DVERSION=""
	[ "$KEYFILE" = "" ] && echo "Unknown" && return
	KFILE=$(echo "$KEYFILE" | cut -d',' -f1)
	KBASE=$(basename "$KFILE")
	KSUBDIR=$(basename "$(dirname "/$KFILE")")
	[ "$KSUBDIR" = "/" ] && KSUBDIR=""
	# Windows and etc.
	case $KBASE in
		bootmgr)  DNAME="Windows" ;;
		ntldr) DNAME="Windows old"
			[ -f $TOPDIR/boot.ini ] && DNAME=$(grep 'WINDOWS=' $TOPDIR/boot.ini| head -n 1| cut -d'=' -f2| cut -d'/' -f1|  tr -d '"' | trim)
			[ "$DNAME" = "" ] && DNAME="Windows NT/2000/2003/Xp"
			;;
		io.sys) DNAME="MSDOS";;
		plpbt.bin) DNAME="PLOP_boot_manager";;
		rootfs*.gz) DNAME="Slitaz Linux";;
		puppy.sfs) # frugal installed Puppy with simple file name
			DISTRO_IDSTRING=$(tail -c 16 $TOPDIR$KEYFILE)
			DVERSION=$(echo $DISTRO_IDSTRING| cut -b1-6| tr -dc 'a-z0-9')
			MAJOR=$(echo $DVERSION | cut -b1-4)
			MINOR=$(echo $DVERSION | cut -b5-6| tr -dc '0-9')
			[ "$MINOR" = "" ] && MINOR=0
			[ $MINOR -eq 0 ] && DVERSION=$MAJOR || DVERSION=$MAJOR-$MINOR
			[ "$DVERSION" != "" ] || DVERSION=$SUBDIR
			DNAME="Puppy_$DVERSION"
			;;
		easy.sfs) DNAME="EasyOS"
			#D=$TOPDIR/easyos/releases
			#[ -d "$D" ] && DANME=$(cd $D; ls easy-* | tail -n1)
			;;
		*.sfs) # frugal installed Puppy
			DNAME=$(basename $KBASE .sfs| tr '-' '_')
			[ "$SUBDIR" = "puppylivecdbuild" ] && DESTRO_NAME="${DNAME}_custom"
			;;
		DISTRO_SPECS) #full installed puppy
			DNAME="$(grep '^DISTRO_NAME=' $TOPDIR/etc/DISTRO_SPECS| cut -f2 -d'=' | tr -d "'") $(grep '^DISTRO_VERSION=' $TOPDIR/etc/DISTRO_SPECS| cut -f2 -d'=' | tr -d "'")"
			;;
		initrd) DNAME="Fatdog64"
			F=$TOPDIR/VERSION
			[ -f "$F" ] && DNAME=$(grep 'Fatdog' "$F"| sed -e 's/ version : /-/') 
			;;
		initrd*|vmlinuz)
			# full installed Puppy
			[ -f $TOPDIR/etc/rc.d/PUPSTATE ] && DNAME="Puppy"
			[ -f $TOPDIR/etc/puppyversion ] && DNAME="Puppy" && DVERSION="$(cat $TOPDIR/etc/puppyversion)" #old pre-w464 install.
			[ -f $TOPDIR/etc/DISTRO_SPECS ] && DNAME="$(grep '^DISTRO_NAME=' $TOPDIR/etc/DISTRO_SPECS| cut -f2 -d'=' | tr -d "'") $(grep '^DISTRO_VERSION=' $TOPDIR/etc/DISTRO_SPECS| cut -f2 -d'=' | tr -d "'")"
			[ "$DNAME" ] && echo "$DNAME" && return
			# other linux
			 lookup_release && echo "$DNAME" && return
				#3jun12 v1.7.9.x: vmlinuz-* may have some information
					S="$SUBDIR"; [ "$S" ] && S="/$S"
					#debug  "$TOPDIR$S/vmlinuz-*"
					V=$(ls -1 "$TOPDIR$S"/vmlinuz-* 2>/dev/null|tail -n1)
					[ "$V" ] && DNAME=$(basename "$V"| sed -e 's/vmlinuz/Linux/' | tr '.-' '_')
				 [ "$DNAME" ] && echo "$DNAME" &&  return
					DNAME="Linux"
					[ "$SUBDIR" != "" ] && DNAME="$DNAME $SUBDIR"
			;;
		menu.lst)
			DNAME=$(grep -v '^[[:blank:]]*#' $TOPDIR$KEYFILE | grep '^[[:blank:]]*title'| head -n 1 | sed -e 's/^[[:blank:]]*title.//i')
			echo "$DNAME" | grep -q 'find[[:blank:]]*/' && DNAME=$(echo "$DNAME" | cut -d'/' -f2)
			;;
		grub.cfg) #grub2
			DNAME=$(grep -m1 -o "^[ ]*menuentry[ ]'[^\']*'" $TOPDIR$KEYFILE | cut -s -f2 -d' '| cut -f1 -d','| tr -d "'")
			[ "$DNAME" ] || DNAME=$(grep -m1 -o "^[ ]*menuentry[ ][^ ]*" $TOPDIR$KEYFILE | cut -f2 -d' '| tr -d "'")
			lookup_release
			;;
		syslinux.cfg)
			DNAME=$(grep -m1 "^[ ]*menu[ ][ ]*title" $TOPDIR$KEYFILE | sed -e "s/^.*title//" | tr -d "'")
			;;
		*.cfg)
			#porteus.cfg
			#v1.8.9
			DNAME=""
			for W in title 'menu.label' label; do
				DNAME=$(grep -i "$W" $TOPDIR$KEYFILE| head -n 1)
				if [ "$DNAME" ]; then
					DNAME=$(echo "$DNAME" | sed -e 's/^.*'$W' //i')
					break
				fi
			done
			;;
	esac
	[ "$DNAME" ] && echo "$DNAME" || echo "Unknown"
}

# v2.0.2: ex. sda1 to sda, mmcblk0p1 to be mmcblk0, and nvme0n1p1 to nvme0n1
part2drive() {
	sed -e '/\([0-9]n[0-9]$\|mmcblk[0-9]$\)/! s/[0-9]*$//' -e 's/\([0-9]\)p$/\1/'
}
#v1.7.9
# [hs]d[a-z][0-9] --> (hdX,Y)
# ex. sda2 --> (hd0,1)
X=0
Y=0
partname2num() {
	[ "$1" ] && PART=$1
	DRIVE=$(echo $PART | part2drive) 
	Y=$(echo $PART | sed -e 's/^.*[a-z]//'| tr -dc '0-9') 
	#debug "$DRIVE:$PART:$N"
	[ "$Y" ] || Y=1	# precaution
	[ $COMPAT_MENU -lt 2 ] && Y=$(expr $Y - 1)
	X=0
	[ "$DRIVE" = "$WHERETO" ] && return
	[ "$SWAPPED" != "" ] && return
	echo "$DRIVES" | grep -qw "$DRIVE" || return
	for L in $DRIVES
	do
		echo "$L" | grep -qw "$DRIVE" && break
		X=$(expr $X + 1)  
	done
	[ "$REPLACE" != "" ] && X=$(expr $X + 1)
}

###fixme
swapping() {
	SWAPPED=""
	DRIVE=$(echo $1| part2drive) # v1.7.2
	[ "$DRIVE" = "$TODRIVE" ] && return
	X=0
	case "$DRIVE" in
		*[0-9]) PART1="${DRIVE}p1" ;;
		*)      PART1="${DRIVE}1" ;;
	esac
	partname2num "$PART1"
	[ $X -eq 0 ] && return
	echo "  map (hd$X) (hd0)
map (hd0) (hd$X)"
	SWAPPED="true"
	X=0
	[ "$LEGACY_MENU" = "true" ] && return
	echo "  map --hook"
}

# v2.0.2: add SPLASH image and icon to grub2 boot screen
menuheader() {
		COLOR_NORMAL="white/black"
		COLOR_HIGHLIGHT="black/yellow"
		[ "$TOFIRST" ] || COLOR_HIGHLIGHT="black/white"
		[ "$TOREMOVABLE" ]  && COLOR_HIGHLIGHT="black/cyan"
		SPLASH=$SPLASHPATH
		if [ -z "$SPLASH" ]; then
			SPLASH=/
			[ -s "$TOPDIR$SPLASH" ] || SPLASH=/
		fi
		SPLASH="/$(basename "$SPLASH")"
		if [ -s "$SPLASHPATH" ]; then
			cp -vfr "$SPLASHPATH" "$TOPDIR" >> "$MYLOG"
			[ "$TOREMOVABLE" ] && [ -s "$ANOTHER_BACKGROUND" ] && cp -vf "$ANOTHER_BACKGROUND" "$TOPDIR$BACKGROUND_PATH" >> "$MYLOG"
		fi
		SPLASHIMAGE="gfxmenu=$SPLASH"
		echo "# $MENUFILE produced by $CREDIT"
		if [ $COMPAT_MENU -eq 2 ]; then
			[ "$GRAPHICAL" = "true" ] && COMMNT="" || COMMENT="#"
			echo "set default=$GRUB_DEFAULT
set timeout=10			
insmod all_video
insmod gfxterm
insmod png
insmod jpeg
terminal_output gfxterm
set menu_color_highlight=yellow/blue
set gfxmode=auto
${COMMENT}set theme=/theme/puppy/theme.txt
# Setting the boot screen font via theme.txt
# will fail, so we use loadfont in grub.cfg.
loadfont /theme/puppy/DejaVuSansMono18.pf2"
		fi
}

entrybegin() {
	echo
	if [ $COMPAT_MENU -eq 2 ]; then
		[ "$ONLYIF" ] && echo $ONLYIF
		echo "menuentry '$1' --class puppylinux{"
	else
		echo "title $1"
	fi
}

entryend() {
	[ $COMPAT_MENU -ne 2 ] && return
	echo "}"
	[ "$ONLYIF" ] && echo "fi"
}

setroot() {
	# print set root line according COMPAT_MENU - 0:Legacy, 1:Grub4Dos(default), 2:Grub2
	# environment:
	#  WHERETO, SWAPPED, REPLACE
	#  DRIVES, PCPARTS, BULKIDS, SEARCHPATH, COMPAT_MENU
	# require:
	#  partname2num
	# usage:
	#   SET_ROOT=$(setroot $PART) 
	echo -n "  "	# two space indent
	[ "$1" ] && PART="$1"
	TYPE=$(echo "$PCPARTS"|grep -w "/dev/$PART"| cut -d'|' -f2)
	#v1.9.1: use uuid for full installs
	DRIVE=$(echo $PART| part2drive) 
	
	UUID=""
	if [ "$BULKIDS" != "" -a $COMPAT_MENU -gt 0 ] && echo $TYPE| grep -qE $SUPPORT_FSS; then
		for W in $(echo "$BULKIDS"| grep -w "^/dev/$PART" | cut -d':' -f2);do
			echo $W|grep -qw 'UUID' || continue
			UUID=$(echo $W|cut -d'=' -f2| tr -d '"')
		done
	fi
	if [ "$UUID" != ""  ]; then
		[ $COMPAT_MENU -eq 2 ] && echo "search --no-floppy --set=root --fs-uuid $UUID" && return 0
		# this works for all grub4dos versions
		echo "find --set-root uuid () $UUID" && return 0
	fi
	# if the psubdir is duplicated with others, search file cannot applied 
	if [ "$SEARCHPATH" -a "$DUP" ]; then
		echo "$DUP" | grep -q $(dirname  "$SEARCHPATH") && SEACHPATH=""
	fi
	if [ "$SEARCHPATH" ]; then
		#[ "$SEARCHPATH" -a "$SUBDIR" ] || SEARCHPATH=/$SUBDIR/initrd.gz
		[ $COMPAT_MENU -eq 1 ] && echo "find --set-root --ignore-floppies --ignore-cd $SEARCHPATH" && return 0
		[ $COMPAT_MENU -eq 2 ] && echo "search --no-floppy --file --set=root $SEARCHPATH" && return 0
	fi
	X=0
	Y=0
	partname2num $PART
	[ $COMPAT_MENU -eq 2 ] && echo "set root='(hd$X,$Y)'" && return 0
	echo "root (hd$X,$Y)"
	return 0
}

trim() {
	read X
	echo $X
}

LABELS=""
unique() {
	#echo "$LABELS"
	#echo "$L"
	mySUFF=0
	myLABEL="$L"
	while [ "$LABELS" != "" ] && echo "$LABELS" | grep -q "^$myLABEL$"
	do
		mySUFF=$(expr $mySUFF + 1)
		myLABEL="$L $mySUFF"
	done
	LABELS="$LABELS
$myLABEL"
	L="$myLABEL"
}

make_label() {
	P=$(echo $ITEM|cut -d'|' -f1|cut -d',' -f1)
	echo "$P" | grep -q '/' && P=$(dirname "/$P")
	P1=$(echo $P|cut -d'/' -f 2)
	P2=$(echo $P|cut -d'/' -f 3)
	P=$P1
	[ "$P2" != "" ] && P="$P1/$P2"
	L="$(echo $ITEM|cut -d'|' -f2 | tr '_' ' ')"
	L="$(echo $L|cut -c1|tr 'a-z' 'A-Z')$(echo $L|cut -c2-)"
	#unique
	[ "$PBR" != "" ] && L="$L ($P1$PBR)" || L="$L ($P)"
}

LAST_BOOT_PART_DRIVE=""
LAST_BOOT_PART=""
PARTEDOUT=""
MBR_GAP=0

# v2.0.2: replace fdisk with parted in is_gpt function
is_gpt() {
	myDRIVEDEV=$(echo $1| part2drive) # v1.7.2
	echo $myDRIVEDEV | grep -q '/' || myDRIVEDEV="/dev/$myDRIVEDEV"
	rm -f "$MYLOG2"
	PARTEDOUT=$(parted $myDRIVEDEV print 2>$MYLOG2)
	[ -s "$MYLOG2" ] && cat "$MYLOG2" >> $MYLOG
	echo "$PARTEDOUT" | grep -qi 'gpt' && GPT="y" || GPT=""
	[ "$GPT" ]
}

# v2.0.2: replace fdisk with parted in boot_part function
boot_part() {
	local myDRIVEDEV=$(echo $1| part2drive) # v1.7.2
	echo $myDRIVEDEV | grep -q '/' || myDRIVEDEV="/dev/$myDRIVEDEV"
	[ "$myDRIVEDEV" = "$LAST_BOOT_PART_DRIVE" ] && echo "$LAST_BOOT_PART" && return
	LAST_BOOT_PART_DRIVE=$myDRIVEDEV
	if is_gpt $myDRIVEDEV ;then
		#PARTEDOUT=$(parted $myDRIVEDEV print)
		LAST_BOOT_PART=$(echo "$PARTEDOUT"| awk '/boot/ {print $1}')
		prefix="/dev/"
		string=$myDRIVEDEV
		DRIVEtype=${string#"$prefix"}
		[ $(echo "$DRIVEtype" | grep -E 'mmcblk|nvme') ] && DRIVEtype="$(echo $DRIVEtype)p"
		DRIVEtype+=$LAST_BOOT_PART
		LAST_BOOT_PART=$DRIVEtype
	else
		FDISKOUT=$(LANG=C fdisk -l $myDRIVEDEV)
		LAST_BOOT_PART=$(echo "$FDISKOUT"| grep "^/dev/.*[*]" | cut -d' ' -f1| cut -d'/' -f3)
	fi
	MBR_GAP=$(echo "$PARTEDOUT"| grep -m 1 -o '[0-9]*kB'| tr -dc [0-9])
	echo "MBR_GAP=$MBR_GAP" >> "$MYLOG"
	echo $LAST_BOOT_PART
}

is_bootable() { # v1.7.1 #see MBR boot flag 
	local DEV=$PART
	[ "$1" ] && DEV=$1
	echo $DEV | grep -q '/' || DEV="/dev/$DEV"
	local myDRIVE=$(echo $DEV| part2drive) 
	[ "$(hexdump -n 512 $myDRIVE | tail -n 2 | head -n 1 | cut -d' ' -f9)" = "aa55" ]  || return
	[ "$DEV" = "$myDRIVE" ] && return
	[ "$DEV" = "$(boot_part $DEV)" ] 
}

uefi_bootable() { # see BOOTX64.efi
	[ "$1" ] && L="$1"
	echo "$L" | grep -q '|' || L=$(echo "$PCPARTS" | grep "^/dev/$L|")
	MP=""
	mountpoint "$L" || return
	BOOTX=""
	[ -d "$MP/EFI" ] && BOOTX=$(find  $MP/EFI -mindepth 2 -maxdepth 2 -iname 'bootx64.efi' | grep -m 1 -i '/EFI/boot/')
	[ "$BOOTX" ] ;#&& debug "$BOOTX"
}

# ex. is_removal sda
is_removable() {
	[ "$1" ] && DRIVE=$1
	[ "$DRIVE" ] || return
	REMOVABLE=$(cat /sys/block/$DRIVE/removable)
	[ $REMOVABLE = "1" ]
}
pmediaopt() {
	[ "$1" ] && DRIVE=$1
	PMEDIA="atahd"
	if is_removable; then
		PMEDIA="usbflash"
	else
		$PROBEDISK | grep "/dev/$DRIVE|" | grep -q -w 'SSD' && PMEDIA="ataflash"
	fi
	PMEDIAOPT="pmedia=$PMEDIA"
	echo $PMEDIAOPT
}

#=========================== system check =========================
_NoEFI=$(gettext "Grub2 supports GPT/UEFI under XenialPup 7.5 and later.")
_NoEFIcont=$(gettext "But you can continue without GPT/UEFI support.")
for P in gtk2dialog gtkdialog4 gtkdialog3 gtkdialog; do
	which $P &>/dev/null && GTKDIALOG=$P && break
done
if [ "$GTKDIALOG" = "" ]; then
	echo "'gtkdialog' not found." >&2
	exit 1
fi

# check running under X
if [ "$DISPLAY" = "" ] ; then
	echo "$(basename $0) requires X running. Try 'startx' and re-run '$0'. Goodbye."
	exit 1
fi

export DIALOG=""
export XPID=""
export SMOUNTED=""

if ! [ -f "$LOCAL_HELP" ] ;then
	error_missing  "Hellpfile($LOCAL_HELP)" || exit 0
	LOCAL_HELP=""
fi

PROBEDISK=$(which probedisk2) || PROBEDISK=$(which probedisk) || error_missing --fatal "probedisk"

EFI_SUPPORT="yes"
if !(which efibootmgr &>/dev/null) ; then
	error_missing  "efibootmgr\n$_NoEFI\n$_NoEFIcont"
	EFI_SUPPORT=""
fi
			
# COMPAT_MENU - 0:Legacy, 1:Grub4Dos(default), 2:Grub2
COMPAT_MENU=2

probing start

# v2.0.2: parted probing of drive partitions may result in overlapping
# of ROX desktop drive icons, so we should refresh/realign drive icons.
# v2.1: skip other than woof made puppies
refresh_drive_icons() {
	pidof conky && CONKY_ACTIVE=yes
	pidof ROX-Filer >/dev/null 2>&1 || return
	which pup_event_frontend_d >/dev/null || return
	which clean_desk_icons >/dev/null || return
	which roxfiler >/dev/null || return
	#gtkdialog-splash -close never -timeout 5 -margin 10 -placement bottom-left -fontsize large -bg goldenrod -text "$(gettext 'Refreshing drive icons')  " &
	killall frontend_startup 2>/dev/null
	killall pup_event_frontend_d 2>/dev/null
	pup_event_frontend_d &
	clean_desk_icons
	roxfiler -p "$HOME/Choices/ROX-Filer/PuppyPin"
	if [ "$CONKY_ACTIVE" = "yes" ]; then
		if [ -f $HOME/Startup/conkystart ]; then
			$HOME/Startup/conkystart &
		fi
	fi
}
refresh_drive_icons

# 14jan10 v.1.5.2 again which sfs as PUPSFS
[ -f /etc/rc.d/PUPSTATE ] && . /etc/rc.d/PUPSTATE
MYSFSFILE=$(echo $PUPSFS|cut -d',' -f3)
MYSFSBASE=$(basename "$MYSFSFILE")
PUPPYPREFIX=$(echo $MYSFSBASE|sed -e 's/[0-9].*$//')
MYPART=$(echo $PUPSFS|cut -d',' -f1)
MYDRIVE=$(echo $MYPART| part2drive) # v1.7.2
MYPUPPY=$MYPART$MYSFSFILE

if [ "$PUPMODE" = "2" ];then # v1.9.4 fix for full installed (mavrothal)
 DISTRO_PUPPYSFS="pup_"
 [ -f /etc/DISTRO_SPECS ] && . /etc/DISTRO_SPECS
 MYSFSFILE="${PDEV1},${DEV1FS},/"
 MYSFSBASE="$DISTRO_PUPPYSFS"
 PUPPYPREFIX=$(echo $MYSFSBASE|sed -e 's/[0-9].*$//')
 MYPART="$PDEV1"
 MYDRIVE=$(echo $MYPART| part2drive)
 MYPUPPY=$MYPART$MYSFSFILE
else
 MYSFSFILE=$(echo $PUPSFS|cut -d',' -f3)
 MYSFSBASE=$(basename "$MYSFSFILE")
 PUPPYPREFIX=$(echo $MYSFSBASE|sed -e 's/[0-9].*$//')
 MYPART=$(echo $PUPSFS|cut -d',' -f1)
 MYDRIVE=$(echo $MYPART| part2drive) # v1.7.2
 MYPUPPY=$MYPART$MYSFSFILE
fi

#========= where to install ===========
DISKS=$(probedisk2)
[ "$DISKS" = "" ] && DISKS=$(probedisk)
DISKS=$(echo "$DISKS" |grep -v 'optical' |tr ' ' '_')
PLOCAL=""
BULKIDS="" # partition info
which blkid &>/dev/null && BULKIDS=$(blkid)
MBR_SUPPORT_FSS='vfat|ntfs|ext'	;# v2.1 now supports exr4
SUPPORT_FSS='vfat|ntfs|ext|reiser'
[ $COMPAT_MENU -eq 2 ] && SUPPORT_FSS="$SUPPORT_FSS|f2fs|btrfs|hfs|xfs"
PCPARTS=$(probepart -k|grep -E $SUPPORT_FSS| sort -k 1.6,1.8 -k 1.9n,1 -t'|')  #v1.7.9 sort with key option
PLACELIST=""
NOWDRIVE=""
DRIVES=""
FIRSTDRIVE=""
REMOVABLE=""

# v2.0.2: replace bash 'for' loop with 'while' loop
DISKS=$(echo "$DISKS" > $APPTMP/grub2config.disks)
while read L ; do
	DRIVE=$(echo "$L" | cut -d'|' -f1 | cut -d'/' -f3 )
	[ "$FIRSTDRIVE" ] || FIRSTDRIVE=$DRIVE
	DRIVESIZE=$(parted /dev/$DRIVE print| grep -m1 '^Disk'| awk -F' ' '{print $NF}')
	[ "$DRIVESIZE" ] || continue
	DRIVEINFO="${DRIVESIZE}:_$(echo "$L" | cut -d'|' -f3 )"
	#is_removable && DRIVEINFO="$DRIVEINFO(Removable)"
	PLACELIST="$PLACELIST
$DRIVE|$DRIVEINFO"
done < $APPTMP/grub2config.disks
PLACELIST=$(echo "$PLACELIST" | grep '|')
debug "$PLACELIST"

echo $PARAM1 | grep -q '^/dev/' && PARAM1=$(echo $PARAM1| cut -f3 -d'/')
[ "$PARAM1" ] && WHERETO=$(echo "$PLACELIST" | grep ^$PARAM1)
[ "$WHERETO" ] || WHERETO=$(echo "$PLACELIST" | head -n1)
DEFAULTDRIVE=$(echo "$WHERETO" | cut -f1 -d'|')
N=$(echo "$PLACELIST" | wc --lines)
debug "$N"

#if [ $N -le 1 ] ;then
#	probing end
#else
#debug $(locale)
#=================== choose drive ===================
_Welcome1=$(gettext "Grub2config installs the Grub2 boot loader on a drive.")
_Welcome2=$(gettext "Puppies can be installed using any other tools.")
_BootLoaderTo=$(gettext "Boot loader to")
_Where_tip=$(gettext 'Select the device you would like to boot from. Usually the first drive, but you can select the others if available, or USB removable devices. You may need to change the BIOS setting.')
_Refresh_tip=$(gettext "Probe disks again.")
_OKtoCont=$(gettext "Click 'OK' to continue.")
WELCOME="$_Welcome1\n$_Welcome2"
_Recommended=$(gettext "Recommended")
WHERE=$_BootLoaderTo
#SVGICONS="/usr/share/pixmaps/puppy"
HDD_ICON=$SVGICONS/harddisk.svg
USB_ICON=$SVGICONS/flashcard_usb.svg

DIALOG="<window title=\"$CREDIT\" window-position=\"1\"><vbox>
 <text><input>echo -en \"$WELCOME\"</input></text>
<frame $WHERE>
<text xalign=\"0\" use-markup=\"true\" space-expand=\"true\" space-fill=\"true\"><label>\"(*) : $_Recommended\"</label></text>"

for ITEM in $PLACELIST
do
	DRIVE=$(echo $ITEM | cut -d'|' -f1)
	desc=$(echo $ITEM | cut -d'|' -f2)
	#[ "$DRIVE" = "$DEFAULTDRIVE" ] && DEFAULT='true' || DEFAULT='false'
	[ "$DRIVE" = "$DEFAULTDRIVE" ] && MARK="(*)" || MARK=' '
	#debug  "$DRIVE:$DEFAULTDRIVE:$DEFAULT"
	 DRIVE_ICON=$HDD_ICON
	is_removable $DRIVE && DRIVE_ICON=$USB_ICON
	DIALOG="$DIALOG
		"'<hbox space-expand="false" space-fill="true"> 
          <text xalign="0" use-markup="true" space-expand="false" space-fill="false"><label>"<b>'$DRIVE$MARK'</b> '$desc'"</label></text> 
<text space-expand="true" space-fill="true"><label>" "</label></text><button space-expand="false" space-fill="false"><input file>'$DRIVE_ICON'</input><width>32</width><height>32</height><action type="exit">'$DRIVE'</action></button></hbox>'
done

DIALOG="$DIALOG</frame>
   <hbox>$(make_help_button 'whereto')
	<text><label>\"                                                                                          \"</label></text>
	<button tooltip-text=\"$_Refresh_tip\"><input file stock=\"gtk-refresh\"></input><label>\"$(gettext 'Refresh')\"</label><action>EXIT:REFRESH</action></button>
   <button cancel></button>
  </hbox>
  </vbox></window>"
probing end
RET=$($GTKDIALOG -p DIALOG | grep '^\w\w*=' || echo "$DIALOG" >&2)
eval "$RET"
[ "$EXIT" = "REFRESH" ] && exec $0 $PARAM1
#[ "$EXIT" = "OK" ] || exit 0
#WHERETO=$(echo "$RET" |grep 'true' | cut -d'=' -f1)
WHERETO=$EXIT
echo "$PLACELIST" | grep -q "^$WHERETO" || exit 0

#fi ;#=================================== choose drive END
debug "Choosed:$WHERETO"
DRIVE=""
REPLACE=""
BOOTLOADER=""
WHERETO_INFO=$WHERETO
echo $WHERETO_INFO | grep -q '|'  || WHERETO_INFO=$(echo "$PLACELIST" | grep "$WHERETO" )
WHERETO_INFO=${WHERETO_INFO%%(*}
WHERETO_INFO=$(echo $WHERETO_INFO | tr '_' ' ')
WHERETO=$(echo $WHERETO| sed -e 's/[^0-9a-z].*$//')

whereto_check() {
	debug "Checking $WHERETO/$BOOTPART"
[ "$WHERETO"  ] || WHERETO=$DEFAULTDRIVE
DRIVE=$(echo $WHERETO| part2drive) 
TODRIVE=$DRIVE
TOREMOVABLE=""
#BOOTPART=""
TOFS=""
BOOTABLE_MBR=""
BOOTABLE_UEFI=""
TOFIRST=""
TOGPT=""

	is_removable $WHERETO && TOREMOVABLE="<Removable>" || TOREMOVABLE=""
	echo $WHERETO | grep -q "$FIRSTDRIVE" && TOFIRST="<1st drive>"
	#BOOTPART=$(boot_part $WHERETO)
	is_gpt "$WHERETO" && TOGPT="<GPT>"
	if [ "$BOOTPART" ] ;then
		uefi_bootable $BOOTPART && BOOTABLE_UEFI="<UEFI boot>"
		[ -z "$TOGPT" ] && is_bootable $WHERETO && BOOTABLE_MBR="<MBR boot>"
	fi

[ "$BOOTPART" ] && LPART=$(echo "$PCPARTS" | grep "/dev/$BOOTPART")
[ "$LPART" ] && TOFS=$(echo "$LPART" | cut -d'|' -f2)

_None=$(gettext "None")
[ "$BOOTPART" ] && BOOTPART_STATUS="$BOOTPART($TOFS)" || BOOTPART_STATUS=$_None
BOOTPART_STATUS="$(gettext "Boot Partition"):$BOOTPART_STATUS"
[ "$BOOTPART" -a -z "$(boot_part $WHERETO)" ] && BOOTPART_STATUS="$BOOTPART_STATUS\n'boot' $(gettext 'flag'): $_None"
WHERETO_STATUS="$TOREMOVABLE$TOFIRST$TOGPT$BOOTABLE_UEFI$BOOTABLE_MBR"
WHERETO_STATUS=$(echo $WHERETO_STATUS | sed -e 's/></|/g' | tr -d '<>')
MYTEXT="$WHERETO_INFO\n$WHERETO_STATUS\n$BOOTPART_STATUS"
DRIVE_ICON=$HDD_ICON
[ "$TOREMOVABLE" ] && DRIVE_ICON=$USB_ICON

WHERETO_FRAME="<frame $_BootLoaderTo:>
   <hbox>
   <pixmap><width>48</width>
    <input file>$DRIVE_ICON</input>
   </pixmap>
<text><label>\"$MYTEXT\"</label></text>
<text space-expand=\"true\" space-fill=\"true\"><label>\" \"</label></text>
</hbox>
</frame>"
}
BOOTPART=$(boot_part $WHERETO)
MBR_GAP=$(tail "$MYLOG" | grep 'MBR_GAP=' | cut -f2 -d'='| tr -dc '0-9')
debug "MBR_GAP=$MBR_GAP"
whereto_check

#========== options ============================================
_NextSearch=$(gettext "Click 'OK' to search installed systems.")
_Notask=$(gettext "You chose nothig to do.")
_MenuFrame=$(gettext "Drives to search:")
_BootFrame=$(gettext "Boot loader")
_MakeMenu=$(gettext "Make/Rewrite menu file")
_MakeMenu_tip=$(gettext 'Search and make or rewrite the menu file.')
_MBRinstall=$(gettext "MBR boot loader")
_MBRinstall_tip=$(gettext "Install bootloader so that MBR bootable. Disabled for GPT.")
_UEFIinstall=$(gettext "UEFI boot loader")
_UEFIinstall_tip=$(gettext "Install bootloader so that UEFI bootable.")
_MBR_filesystem=$(gettext "MBR boot only supports")
_UEFI_filesystem=$(gettext "UEFI boot only suppports 'fat32' system.")
_NoSpace=$(gettext "No space to install bootloader.")
_BootPart="$BOOTPART_STATUS"
[ "$BOOTPART" ] || _BootPart="$_BootPart: $(gettext "none")"
echo $_BootPart >> $MYLOG

HELP_SECTION='bootflag'
if [ "$TOFS" ] ;then
	echo "$TOFS" | grep -qE $MBR_SUPPORT_FSS || fatal  "$_BootPart" "$_MBR_filesystem: $MBR_SUPPORT_FSS"
fi
[ -s "$MYLOG2" ] && [ -z "$EFI_SUPPORT" ] && fatal "$(gettext "Seems GPT, which this system does not support.")"
if [ -z "$BOOTPART" ] ;then
	echo "Boot flag not found on $DRIVE" >> $MYLOG
	MSG1="$(printf "$(gettext "No boot flag on %s.")" "$DRIVE")\n$(gettext 'Set the boot flag using GParted or something.')"
	MSG2=$(gettext "But you can proceed as is. Click 'OK'.")
		HELP_SECTION="bootflag"
		EXIT=""
		DRIVE=$WHERETO
		warning "$MSG1" "$MSG2" "$GPARTED_LAUNCHER"	 
		BOOTPART=$(probepart | grep "^/dev/$WHERETO" | head -n 1)
		BOOTPART=${BOOTPART%%|*}
		BOOTPART=${BOOTPART##*/}
		debug "BOOTPART set to '$BOOTPART'."
		whereto_check
fi

MAKE_MENU='true'
#KEEP_MENU='false'
KEEP_BOOT_RECORD='false'
UEFI_INSTALL='true'
UEFI_ENABLE='true'
MBR_INSTALL='true'
MBR_ENABLE='true'
 [ "$TOGPT" ] && MBR_INSTALL='false' && MBR_ENABLE='false'
 [ -z "$TOGPT"  -a -z "$TOREMOVABLE" ] && UEFI_INSTALL='false'
if [ -z "$EFI_SUPPORT" -a -z "$TOREMOVABLE" ] ;then
	UEFI_INSTALL='false'
	UEFI_ENABLE='false'
fi

WARNING=""
if [ "$TOFS" != 'vfat' ] ;then
	[ "$TOGPT" ]  || MBR_INSTALL='true'
	UEFI_INSTALL='false'
	UEFI_ENABLE='false'
	WARNING="<hbox>
	<pixmap icon_size=\"5\">
       <input file stock=\"gtk-dialog-warning\"></input>
     </pixmap>
	<vbox>
	<text><label>$_BootPart</label></text>
	<text><label>\"$_UEFI_filesystem\"</label></text>
</vbox>
</hbox>"
fi

SEARCHDRIVES=""
for ITEM in $PLACELIST
do
	DRIVE=$(echo "$ITEM" | cut -d'|' -f1)
	DEFAULT='true' 
	is_removable && DEFAULT='false'
	[ "$TOREMOVABLE" ] && DEFAULT='false'
	[ "$DRIVE" = "$TODRIVE" ] && DEFAULT='true' 
	SEARCHDRIVES="$SEARCHDRIVES
  <checkbox><label>\"$(echo $ITEM | tr '_' ' ')\"</label><variable>SEARCH_$DRIVE</variable><default>$DEFAULT</default></checkbox>"
done

DIALOG="<window title=\"$CREDIT\"><vbox>
$WHERETO_FRAME
$WARNING
<frame $_MenuFrame>
$SEARCHDRIVES
</frame>
<frame $_BootFrame>
  <checkbox tooltip-text=\"$_MBRinstall_tip\"><label>$_MBRinstall</label><variable>MBR_INSTALL</variable><default>$MBR_INSTALL</default><sensitive>$MBR_ENABLE</sensitive></checkbox>
 <checkbox tooltip-text=\"$_UEFIinstall_tip\"><label>$_UEFIinstall</label><variable>UEFI_INSTALL</variable><default>$UEFI_INSTALL</default><sensitive>$UEFI_ENABLE</sensitive></checkbox>
    </frame>
    <text><label>\"$_NextSearch\"</label></text>
  <hbox>
  $(make_help_button 'options')
  <button ok></button>
  <button cancel></button>
  </hbox>
  </vbox></window>"
eval $($GTKDIALOG -p DIALOG -c | grep '^\w\w*=' || echo "$DIALOG" >&2)
[ "$EXIT" = "OK" ] || exit 0

SEARCHPARTS=""
DRIVELIST=$(echo "$PLACELIST" | cut -d'|' -f1)
#replace order
DRIVELIST="$(echo  "$DRIVELIST" | grep "$WHERETO" )
$(echo "$DRIVELIST" | grep -v "$WHERETO")" 
for DRIVE in $DRIVELIST; do
	eval CHECK=\$SEARCH_$DRIVE
	debug "$DRIVE:$CHECK"
	if [ "$CHECK" = 'true' ] ;then
		PARTS="$(echo "$PCPARTS"| grep "$DRIVE")"
		SEARCHPARTS="$SEARCHPARTS
$PARTS"
	fi
done
SEARCHPARTS=$(echo "$SEARCHPARTS" | grep 'dev')
debug "SEARCHPARTS
$SEARCHPARTS"
debug "PUPPY_DEPTH=$PUPPY_DEPTH"

#[  "$SEARCHPARTS" ] || KEEP_MENU='true'
[ "$UEFI_INSTALL" != 'true' ] && [ "$MBR_INSTALL" != 'true' ] && KEEP_BOOT_RECORD='true'

if [ "$KEEP_BOOT_RECORD" = "true" -a -z "$SEARCHPARTS" ] ;then
		error_missing "$_Notask" || exit 0
		exec $0 "$@"
fi

# file system check
HELP_SECTION="bootflag"
SPACE_NEED=0
if [ "$UEFI_INSTALL" = 'true' ] ;then
	[ "$TOFS" = 'vfat' ] || fatal "$_BootPart" "$_UEFI_filesystem"
	SPACE_NEED=$(($SPACE_NEED + $KSIZE_UEFI))
fi
if [ "$MBR_INSTALL" = 'true' ] ;then
	[ $MBR_GAP -ge 1000 ] || fatal "$_NoSpace" "$(gettext "MBR install needs 1MB 'MBR-gap' before the 1st partition.")"
	SPACE_NEED=$(($SPACE_NEED + $KSIZE_MBR))
fi
SPACE_NEED=$(($SPACE_NEED + $KSIZE_THEME))
LPART=$(echo "$PCPARTS" | grep "/dev/$BOOTPART")
mountpoint $LPART || fatal "Failed mounting:$LPART"
KFREE=$(kbyte_free $MP)
[ "$KFREE" ] || KFREE=0
debug "${KFREE}kB free. Need ${SPACE_NEED}kB."
[ $KFREE -ge $SPACE_NEED ] || fatal  "$_NoSpace" "Need ${SPACE_NEED}kB free space in $BOOTPART. (Now ${KFREE}kB free)"

HELP_SECTION=""

#======================= search ==========================
if [ "$SEARCHPARTS" ] ; then ### long skip

	# search
	probing progress
	LC_ALL_SAVE=$LC_ALL	#v1.7.9
	LC_ALL=C
	PUPPIES=""
	FULLINSTS=""
	WININSTS=""
	BOOTMGRS=""
	DUP=""
	#find boot flags
	#DRIVES=$(echo "$PCPARTS"|cut -d'|' -f1| cut -d'/' -f3| tr -d '0-9'| uniq)
	BOOTPARTS=""
	PART=""
	FAILPARTS=""
	N=$(echo "$SEARCHPARTS" | wc -l)
	STEP=$(expr 100 / $(expr $N + 1))
	I=0
	for L in $SEARCHPARTS
	do
		I=$(expr $I + $STEP)
		percent $I
		mountpoint $L
		if [ -z "$MP" ] ;then
			FAILPARTS="$FAILPARTS $PART($FS)"
			continue
		fi
		TOPDIR=$MP
		KEYFILE=""
		DISTRO=""
		# find vmlinuz
		PUPDIRS=$(find -L $TOPDIR -mindepth 1 -maxdepth $PUPPY_DEPTH -name vmlinuz* -type f 2>$MYLOG2 | sed -e 's,/[^/]*$,,' |uniq)
		debug "PUPDIRS on $PART:"$PUPDIRS
		for D in $PUPDIRS
		do
			SUBDIR=$(echo $D | sed -e "s|$TOPDIR||")
			INITRD=$(basename "$(ls -1 $D/initrd* 2>/dev/null | tail -n1)")	#3jun12 v1.7.9.x, v1.8: revert
			PUPSFS=""
		  if [ -s "$D/vmlinuz" -a "$INITRD" ] ;then
			PUPSFS="$D/$MYSFSBASE"; [ -s "$PUPSFS" ]  || PUPSFS=""
			[ "$PUPSFS" = "" ] && [ -s "$D/puppy.sfs" ] && PUPSFS="$D/puppy.sfs"
			[ "$PUPSFS" = "" ] && [ "$PUPPYPREFIX" != "" ] && PUPSFS="$(ls $D/$PUPPYPREFIX[0-9][0-9.]*.sfs 2>/dev/null|tail -n 1)"
			[ "$PUPSFS" = "" ] && PUPSFS="$(ls $D/puppy*[0-9][0-9.]*.sfs 2>/dev/null|tail -n 1)"
			[ "$PUPSFS" = "" ] && PUPSFS="$(ls $D/pup[_-][0-9][0-9][0-9]*.sfs 2>/dev/null|tail -n 1)"
			[ "$PUPSFS" = "" ] && PUPSFS="$(ls $D/?pup-[0-9][0-9][0-9]*.sfs 2>/dev/null|tail -n 1)"
			if [ "$PUPSFS" = "" ]; then
				PUPSFSES="$(ls $D/[a-zA-Z][0-9a-zA-Z_]*[-_][0-9]*.sfs 2>/dev/null| grep -vE '(?drv|devx)')"
				if [ "$(echo "$PUPSFSES" | wc -l)" -eq 1 ]; then
					PUPSFS=$PUPSFSES
				else
					PUPSFS=$(echo "$PUPSFSES" | grep '/[a-z]*up[^/]*.sfs'| tail -n1)
					[ "$PUPSFS" ] || PUPSFS=$(echo "$PUPSFSES" | tail -n1)
				fi
			fi
		  fi
			if [ "$PUPSFS" ]; then
				#ENTRY=$(echo "$PUPSFS"|sed -e "s,^$TOPDIR/,$PART/,")
				KEYFILE=$(echo "$PUPSFS"|sed -e "s,^$TOPDIR/,/,")
				PDIR=$(echo "$KEYFILE"| cut -s -d '/' -f 2)
				#[ "$PDIR" ] && PDIR="/$PDIR"
				#echo "$PDIR"
				[ "$PDIR" ] && echo "$PUPPIES"| grep -q "/$PDIR/" && DUP="$DUP $PDIR"
				ITEM="$PART$KEYFILE,$INITRD|$(read_distro_name $TOPDIR)"
				#debug "$ITEM"
				PUPPIES="$PUPPIES
$ITEM"
				continue
			elif [ -s "$D/easy.sfs" ] ;then
			# easyos
				#[ -z "$SUBDIR" -a -s "$D/syslinux.cfg" ]  && KEYFILE="/syslinux.cfg" && DISTRO=$(read_distro_name $TOPDIR)
				KEYFILE=$SUBDIR/easy.sfs
				ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
				FULLINSTS="$FULLINSTS
$ITEM"
				continue
			elif [ -z "$SUBDIR"  -o "$SUBDIR" = "/boot"  ] ;then
				KEYFILE=""
				F='grub/grub.cfg'
				if [ -f "$D/$F" ] ;then
					KEYFILE="$SUBDIR/$F"
					DISTRO=$(read_distro_name $TOPDIR)
					if [ $COMPAT_MENU -ne 2 ] ;then
						#read option
						OPTIONS=$(grep 'vmlinuz' "$TOPDIR/$F" | head -n 1 | sed -e s/^.*vmlinuz// -e s/\$.*// )
						KEYFILE=""
					fi
				fi
				F='grub/i386-pc/core.img'
				[ -z "$KEYFILE" -a -f "$D/$F" ] && KEYFILE="$SUBDIR/$F"
				if [ -z "$KEYFILE" ]; then
					INITRD=$(echo $INITRD | cut -d'-' -f1 |cut -d'.' -f1-2) 
					KTAIL=""
					if [ ! -s "$D/vmlinuz" ]  ;then
						KTAIL=$(cd "$D"; ls vmlinuz-* 2>/dev/null | tail -n 1 | sed -e 's/^vmlinuz//')
					fi
					debug "Found:vmlinuz$KTAIL"
					[ -s "$D/$INITRD$KTAIL" ] || continue
					KEYFILE="$SUBDIR/$INITRD$KTAIL"
					[ $COMPAT_MENU -ne 2 -a "$OPTIONS" ]  && KEYFILE="$KEYFILE,$OPTIONS"
				fi
				debug "Other Linux:$KEYFILE, SUBDIR:$SUBDIR, PUPSFS:$PUPSFS"
				[ "$DISTRO" ] || DISTRO=$(read_distro_name $TOPDIR)
				ITEM="$PART$KEYFILE|$DISTRO"
				FULLINSTS="$FULLINSTS
$ITEM"
			fi
		done
		ROOTPUPPY=$(echo "$PUPPIES" | grep -E "^$PART/[^/]*.sfs" | tail -n 1)

		# Wubi
		if [ -f $TOPDIR/ubuntu/disks/boot/grub/menu.lst ];then # ununtu on Windows
			KEYFILE=/ubuntu/disks/boot/grub/menu.lst
			ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
			FULLINSTS="$FULLINSTS
$ITEM"
		fi
		for D in ubuntu jolicloud; do
			if [ -f $TOPDIR/$D/winboot/wubildr.mbr ];then # ununtu on Windows
				KEYFILE=/$D/winboot/menu.lst
				ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
				FULLINSTS="$FULLINSTS
$ITEM"
			fi
		done
		if [ -f $TOPDIR/ubnldr.mbr -a -f $TOPDIR/unetbtin/menu.lst ];then # ununtu on Windows
			KEYFILE=/unetbtin/menu.lst
			ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
			FULLINSTS="$FULLINSTS
$ITEM"
		fi
		#v1.8: slitaz
		SLITAZES=$(find -L $TOPDIR -mindepth 1 -maxdepth 2 -name rootfs*.gz -type f| rev | cut -f2- -d'/' | rev| sort -u)
		if [ "$SLITAZES" ]; then
			for D in $SLITAZES; do
				[ -s "$D/bzImage" ] || continue
				S=$(echo $D| sed -e "s,^$TOPDIR,,")
				if [ -s "$D/rootfs.gz" ]; then
					ROOTFSES="rootfs.gz"
				else
					ROOTFSES=$(find -L $D -mindepth 1 -maxdepth 1 -name rootfs[1-9].gz -type f -printf ',%P' | cut -b2-)
				fi
				KEYFILE="$S/$ROOTFSES"
				ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
				FULLINSTS="$FULLINSTS
$ITEM"
			done
		fi
		#v1.8.9: porteus
		if [ -d $TOPDIR/porteus -a -f $TOPDIR/boot/syslinux/porteus.cfg ]; then
			KEYFILE="/boot/syslinux/porteus.cfg"
			ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
			FULLINSTS="$FULLINSTS
$ITEM"
			# save cache
			mkdir -p "$(dirname "$APPTMP/$PART$KEYFILE")"
			cp "$TOPDIR$KEYFILE" "$APPTMP/$PART$KEYFILE"
		fi

		# windows legacy
		for F in bootmgr ntldr io.sys ; do
			if [ -f $TOPDIR/$F ]; then
				KEYFILE="/$F"
				ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
				WININSTS="$WININSTS
$ITEM"
				break
			fi
		done

		# plop
		if [ "$PLOPINSTS" = "" ]; then
			KEYFILE=""
			for D in /boot/ /; do
				F="${D}plpbt.bin"
				[ -s $TOPDIR$F ] && KEYFILE="$F" && break
			done
			if [ "$KEYFILE" != "" ]; then
				ITEM="$PART$KEYFILE|$(read_distro_name $TOPDIR)"
				BOOTMGRS="$BOOTMGRS
$ITEM"
			fi
		fi
		
		if uefi_bootable  ;then
			WINEFI=$(find -L "$TOPDIR/EFI" -mindepth 3 -maxdepth 3 -iname 'bootmgfw.efi' -type f| sed -e "s|$TOPDIR|$PART|")
			LINEFI=$(find -L "$TOPDIR/EFI" -mindepth 2 -maxdepth 2 -iname 'shim*.efi' -type f | head -n 1 | sed -e "s|$TOPDIR|$PART|")
			TOPEFI=$(find -L "$TOPDIR/EFI" -mindepth 2 -maxdepth 2 -iname 'bootx64.efi' -type f | grep -i '/EFI/boot/'| sed -e "s|$TOPDIR|$PART|")
			[ "$WINEFI" ] && WINEFIS="$WINEFIS
$WINEFI"
			[ "$LINEFI" ] && LINEFIS="$LINEFIS
$LINEFI"
			[ "$TOPEFI" ] && TOPEFIS="$TOPEFIS
$TOPEFI"
		fi

		#
		KEYFILE=""
		umountmine
	done
	#v1.8: fatdog64
	FATDOGS=$(echo "$FULLINSTS"| grep  '/initrd,')
	if [ "$FATDOGS" ]; then
		FULLINSTS=$(echo "$FULLINSTS"| grep -v '/initrd,')
		PUPPIES="$PUPPIES
$FATDOGS"
	fi
	# v2.1.1: sort
	PUPPIES=$(echo "$PUPPIES"| grep '/' | sort -f)
	FULLINSTS=$(echo "$FULLINSTS"| grep '/'| sort -f)
	WININSTS=$(echo "$WININSTS"| grep '/')
	BOOTMGRS=$(echo "$BOOTMGRS"| grep 'plpbt.bin'| head -n 1) # take only the 1st PLOP
	
	# pmedia option
	PUPPYDRIVE=$(echo "$PUPPIES"| cut -d'/' -f1| part2drive | uniq) # v1.7.2
	#debug "PUPPYDRIVE=$PUPPYDRIVE;"
	if [ $(echo "$PUPPYDRIVE" | wc -l) -eq 1 ]; then
		PMEDIAOPT=$(pmediaopt $PUPPYDRIVE)
		PUPPYOPTIONS="$PMEDIAOPT $PUPPYOPTIONS"
	fi

	# which puppy is better at the top? #v1.9
	debug "MYPUPPY=$MYPUPPY"
	NPUP=$(echo "$PUPPIES"| wc -l)
	if [ "$MYPUPPY" = "" ]; then
		[ -s /etc/DISTRO_SPECS ] && source /etc/DISTRO_SPECS
		[ "$DNAME" = "Fatdog64" ] && MYPUPPY="Fatdog64"
	fi
	TOPPUPPY=$MYPUPPY
	if [ "$MYPUPPY" != "" -a $NPUP -gt 1 ]; then
		TOPPUPPY=$(echo "$PUPPIES"| grep -w "$MYPUPPY" | head -n 1)
		[ "$TOPPUPPY" = "" ] && TOPPUPPY=$(echo "$PUPPIES"| grep -w $(basename "/$MYPUPPY") | head -n 1)
		[ "$(echo $MYDRIVE| cut -b2)" = "d" ] && MYREMOVABLE=$(cat /sys/block/$MYDRIVE/removable)|| MYREMOVABLE="1"
		[ "$TOPPUPPY" = "" ] && TOPPUPPY=$(echo "$PUPPIES"| grep -Ew "^$TODRIVE.*$MYSFSBASE"| head -n 1)
		if [ "$TOPPUPPY" = "" -a "$TOREMOVABLE" = "0" ]; then  
			for P in $(echo "$PUPPIES"| grep -w "$MYSFSBASE"); do
				D=$(echo $P|cut -d'/' -f1| tr -d '0-9')
				[ "$(cat /sys/block/$D/removable)" = "0" ] && TOPPUPPY=$P && break
			done
		fi
		if [ "$TOPPUPPY" != "" ]; then
			PUPPIES=$(echo "$PUPPIES"| grep -vx "$TOPPUPPY")
			PUPPIES="$TOPPUPPY
$PUPPIES"
		fi
		if [ "$TOREMOVABLE" = "1" -o "$MYREMOVABLE" = "1" ]; then
			MYPUPPY=$(echo "$PUPPIES"| grep -Ew "^$TODRIVE.*$MYSFSBASE"| head -n 1)
			[ "$MYPUPPY" = "" ] && MYPUPPY=$(echo "$PUPPIES"| grep "^$TODRIVE"| head -n 1)
			if [ "$MYPUPPY" != "" ]; then
				PUPPIES=$(echo "$PUPPIES"| grep -vx "$MYPUPPY")
				PUPPIES="$MYPUPPY
$PUPPIES"
			fi
		fi
	fi
	PUPPIES=$(echo "$PUPPIES"| grep '/')
	debug "PUPPIES:$PUPPIES
FULLINSTS:$FULLINSTS
WININSTS:$WININSTS
BOOTMGRS:$BOOTMGRS
WINEFIS:$WINEFIS
LINEFIS:$LINEFIS
TOPEFIS:$TOPEFIS"
 
	percent 100
	#probing end
		###fixme### etx4-64bit check
		debug "COMPAT_MENU=$COMPAT_MENU"

	LC_ALL=$LC_ALL_SAVE

	# ======================= make list ====================================
_List=$(gettext "List of detected operating systems")
_List2=$(gettext "You can rewrite each label or erase. You cannot change their order. You can edit the menu file after.")
_Puppy=$(gettext "Puppy Linux")
_Full=$(gettext "Other Linux")
_Win=$(gettext "Windows")
#_Win2=$(gettext "Grub4DosConfig does not check any Windows installed or not. But you can put items on the menu to bootup Windows if installed.")
_Win3="$(gettext "This entry is always shown regardless Windows are installed or not.")\n$(gettext "Erase the entry if you need not.")" 
#Recommended to keep the entry.erase it if you not need.
_Chain_frame=$(gettext 'Bootable partitions')
_Puppy_opt=$(gettext "Options")
_Puppy_opt_tip=$(gettext "You can edit the boot options add to all frugal installed Puppy.")
_Linux_opt=$(gettext "Options")
_Linux_opt_tip=$(gettext "You can edit the boot options add to all full installed Linux.")
_Failed=$(gettext "Failed to search in partitions")
_Not_found=$(gettext 'Not found')

ENTRY_WIDTH=400	;###fixme seems not work

PBR=""	# for making label

	# failed parts
	FAILED_BOX=""
	if [ "$FAILPARTS" ] ;then
		FAILED_BOX="<hbox>
	<pixmap icon_size=\"5\">
       <input file stock=\"gtk-dialog-warning\"></input>
  </pixmap>
  <text><input>echo -en \"$_Failed:$FAILPARTS\"</input></text>	
</hbox>"
	fi

	# Puppy list
	NPUP=0
	FRAME="<frame $_Puppy><vbox>"
	if [ "$PUPPIES" = "" ];then
		FRAME="$FRAME
<text><label>($_Not_found)</label></text>"
	else
		NPUP=$(echo "$PUPPIES" | wc -l)
		I=0
		for ITEM in $PUPPIES
		do
			I=$(expr $I + 1)
			make_label
			FRAME="$FRAME
  <entry><width>$ENTRY_WIDTH</width><variable>Frugal_$I</variable><default>$L</default></entry>"
		done
		# option box
		FRAME="$FRAME
  <hbox>
  <text><label>$_Puppy_opt</label></text>
  <entry tooltip-text=\"$_Puppy_opt_tip\"><variable>PUPPYOPTIONS</variable><input>echo -en \"$PUPPYOPTIONS\"</input></entry>
  </hbox>
"
	fi
	FRUGALFRAME="$FRAME
   </vbox></frame>"

	# full installs
	FULLFRAME=""
	NFULL=$(echo "$FULLINSTS" | wc -l)
	NFULL=0
	if [ "$FULLINSTS" != "" ];then
		NFULL=$(echo "$FULLINSTS" | wc -l)
		ADDOPT=""
		FRAME="<frame $_Full><vbox>"
		I=0
		FULLITEMS=$(echo "$FULLINSTS" | tr ' ' '_')
		for ITEM in $FULLITEMS
		do
			#echo $ITEM
			I=$(expr $I + 1)
			make_label
			FRAME="$FRAME
<entry><variable>Full_$I</variable><default>$L</default></entry>"
		done
		FULLFRAME="$FRAME
 </vbox></frame>"
	fi

	# entries for Windows
	#v1.8.9: multiple Windows in the advaced list
	NWIN=1
	WINFRAME="<frame $_Win><vbox>
<text><input>echo -en \"$_Win3\"</input></text>
  <entry><variable>Win_0</variable><default>Windows</default></entry>
</vbox></frame>"
DEFAULT='true'
GRAPHICAL=$DEFAULT
	GRAPHICAL_CHECK="<checkbox tooltip-text=\"$(gettext 'Make the boot menu with graphical icons.')\"><label>\"$(gettext "Graphical menu")\"</label><variable>GRAPHICAL</variable><default>$DEFAULT</default></checkbox>"

	# main frame
	WIDTH=640
	LFRAMES="<vbox>
<text space-expand=\"true\" space-fill=\"true\"><input>echo -en \"$_List2\"</input></text>
$FRUGALFRAME
</vbox>"
	RFRAMES="<vbox>
	$FAILED_BOX
	$FULLFRAME
	$WINFRAME
	$GRAPHICAL_CHECK
	</vbox>"
	DIALOG="<window title=\"$CREDIT - $_List\" default-width=\"$WIDTH\"><vbox>
<hbox>
   $LFRAMES
	$RFRAMES
 </hbox>
  <hbox>
   "$(make_help_button "menutitles")"
   <button ok></button>
   <button cancel></button>
  </hbox>
</vbox></window>"
	probing end
	#debug "$DIALOG"
	#[ "$DEBUGFLAG" ] && echo "$DIALOG" > /tmp/$APPNAME-dialog
	eval $($GTKDIALOG -p DIALOG -c | grep '^\w\w*=' || debug "$DIALOG")
	[ "$EXIT" = "OK" ] || exit 0
fi ### long skip

#======================== write menu ============================
_Writing=$(gettext "Installing.")
_Writing_menu=$(gettext "Writing menu.")

whereto_check

pupopt() {
	#in: DRIVE PUPDIR, PMEDIA, SFSPATH, INITRDGZ
	PMEDIAOPT=""
	if [ "$PMEDIA" = "" ]; then
		PMEDIA="atahd"
		#REMOVABLE="$(cat /sys/block/$DRIVE/removable)"
		if is_removable $DRIVE; then
			PMEDIA="usbflash"
		else
			$PROBEDISK | grep "/dev/$DRIVE|" | grep -q -w 'SSD' && PMEDIA="ataflash"	#v1.8
		fi
		PMEDIAOPT="pmedia=$PMEDIA"
	fi
	if [ "$PUPDIR" = "/" ] ;then
		PUPDIR=""
		PSUBDIROPT=""
		SEARCHPATH="$SFSPATH"
	else
		PSUBDIROPT="psubdir=/$(echo $PUPDIR| cut -d '/' -f 2-)"
		SEARCHPATH="$PUPDIR/$INITRDGZ"
	fi
}
puppy_entry() {
	local PFIX=$1
	local MYOPTIONS=$PUPPYOPTIONS
	if [ "$PFIX" ] ; then
		echo $MYOPTIONS | grep -q 'pfix=' \
		 && MYOPTIONS=$(echo $MYOPTIONS| sed -e "s/pfix=[^ ]*/pfix=$PFIX/") \
		 || MYOPTIONS="$MYOPTIONS pfix=$PFIX"
	fi
	entrybegin "$LABEL"  >> $MENU
	setroot >>  $MENU
	# pdrv option - must be after running setroot
	PDRVOPT=""
	[ "$UUID" ] && PDRVOPT="pdrv=$UUID"
	echo "  $KERNEL $PUPDIR/vmlinuz $CLASSICOPT $PDRVOPT $PMEDIAOPT $PSUBDIROPT $MYOPTIONS" >> $MENU
	echo "  if [ -e $PUPDIR/ucode.cpio ]; then
    initrd $PUPDIR/ucode.cpio $PUPDIR/$INITRDGZ
  else
    initrd $PUPDIR/$INITRDGZ
  fi" >> $MENU
	entryend  >>  $MENU
}
LABEL=""
PUPDIR=""
INITRDGZ=""

WRITING="$_Writing"
[ "$KEEP_BOOT_RECORD" = 'true' ] && WRITING="$_Writing_menu"
splash start "$WRITING"
 mountpoint $LPART || fatal "Failed mounting:$LPART"
	TOPDIR=$MP
	TOPPART=$PART
	#TODRIVE=$TOPPART
	#TODRIVE=$(echo $TOPPART| tr -d '0-9')
	TOPFS=$FS
	MENUFILE="menu.lst"
	[ $COMPAT_MENU -eq 2 ] && MENUFILE="grub.cfg"
	MENU="$TOPDIR/$MENUFILE"
	#echo "$MENU"
	if [ "$SEARCHPARTS" ] ; then	### skip menu
		# produce menu file

		ONLYIF=""
		FIND_SETROOT="find --set-root --ignore-floppies --ignore-cd "
		KERNEL="kernel"
		if [ $COMPAT_MENU -eq 2 ]  ;then
			FIND_SETROOT="search --no-floppy --set=root --file "
			KERNEL="linux"
		fi

		# save backup
		OLDMENU=""
		F=$(find $TOPDIR -maxdepth 1 -iname "$MENUFILE" -type f)
		if [ "$F" ] ;then
			OLDMENU="${MENUFILE%.*}-prev.${MENUFILE##*.}"
			rm -f $TOPDIR/$OLDMENU
			mv -f $F $TOPDIR/$OLDMENU
			debug "Old menu '$F' is backuped as '$OLDMENU'."
		fi
		echo "Writing... $MENU" >>$MYLOG
		menuheader>  $MENU 2>>$MYLOG

		#frugal entries
		TOPPUPPY=""
		I=0
		if [ "$PUPPIES" != "" ]; then
			echo "
# Puppy Linux"  >>  $MENU
		fi
		RAMLABEL=""
		debug "$PUPPIES"
		for ITEM in $PUPPIES
		do
			I=$(expr $I + 1)
			eval LABEL=\$\(echo \"\$Frugal_$I\"\|trim\)
			[ "$LABEL" = "" ] && continue
			NEWITEM=$(echo $ITEM|cut -d'|' -f1)
			#debug $NEWITEM
			PART=$(echo $NEWITEM|cut -d '/' -f1)
			SFSPATH=$(echo $NEWITEM | cut -f1 -d',' | sed -e 's,^[^/]*,,')
			SFSBASE=$(basename "$SFSPATH")
			PUPDIR=$(dirname $SFSPATH)
			DRIVE=$(echo $ITEM | cut -d '/' -f 1 | part2drive) # v1.7.2
			KEYFILE=$(echo $NEWITEM | cut -s -f2 -d',')	# | rev | cut -f1 -d'/' | rev)
			INITRDGZ=initrd.gz
			if echo $KEYFILE | grep -q 'initrd'; then
				INITRDGZ=$KEYFILE
			else #fatdog
				INITRDGZ=$(basename $SFSPATH | grep 'initrd')
			fi
			PMEDIA=""
			PFIX=""
			if [ "$PUPPYOPTIONS" != "" ]; then
				for W in $PUPPYOPTIONS; do
					P=$(echo $W | cut -s -d'=' -f1|tr 'A-Z' 'a-z')
					[ "$P" != "" ] || continue
					V=$(echo $W | cut -d'=' -f2)
					case $P in
						pmedia) PMEDIA=$V;;
						pfix) PFIX=$V;;
					esac
				done
			fi
			PMEDIAOPT=""
			if [ "$PMEDIA" = "" ]; then
				PMEDIAOPT=$(pmediaopt $DRIVE)
			fi
			if [ "$PUPDIR" = "/" ] ;then
				PUPDIR=""
				PSUBDIROPT=""
				SEARCHPATH="$SFSPATH"
			else
				PSUBDIROPT="psubdir=/$(echo $PUPDIR| cut -d '/' -f 2-)"
				SEARCHPATH="$PUPDIR/$INITRDGZ"
			fi
			HEAD4=$(echo $SFSBASE | cut -b1-4)
			MAJOR=$(echo $SFSBASE | cut -b5| tr -dc '0-9')
			[ "$MAJOR" = "" ] && MAJOR=9
			CLASSICOPT=""
			[ "$HEAD4" = "pup_" -a $MAJOR -lt 3 ] && CLASSICOPT="root=/dev/ram0"
			#echo >>  $MENU
			puppy_entry
			if [ "$TOPPUPPY" = "" ]; then
				TOPPUPPY="$LABEL"
				echo $LABEL| grep -q '(' && LABEL="${LABEL%\(*} RAM mode(${LABEL##*\(}" || LABEL="%LABEL RAM mode"
				puppy_entry ram
			fi
		done

		#full installed entries
		SEARCHPATH=""  #v1.9.1
		I=0
		if [ "$FULLINSTS" != "" ]; then
			echo "
# Other Linux"  >>  $MENU
		fi
		for ITEM in $FULLITEMS
		do
			I=$(expr $I + 1)
			eval LABEL=\$\(echo \"\$Full_$I\"\|trim\)
			[ "$LABEL" = "" ] && continue
			NEWITEM=$(echo $ITEM|cut -d',' -f1)
			NEWITEM=$(echo "$FULLINSTS" | grep ^$NEWITEM |cut -d'|' -f1)
			debug "$NEWITEM"
			PART=$(echo $NEWITEM|cut -d '/' -f1)
			DRIVE=$(echo $PART | part2drive)	#v1.8
			KEYFILE=$(echo $NEWITEM | sed -e 's,^[^/]*,,')
			KEYFILE2=$(echo $KEYFILE| cut -s -d',' -f2)	# can be options
			KEYFILE1=$(echo $KEYFILE| cut -d',' -f1)
			KDIR=$(dirname $KEYFILE1)
			[ "$KDIR" = "/" ] && KDIR=""
			KBASE=$(basename $KEYFILE1)
			KBASE2=$(basename "$KEYFILE2")
			#echo  >>  $MENU
			entrybegin "$LABEL"  >>  $MENU
###fixme			[ "/mnt/$PART" = "$TOPDIR" -a "$KEYFILE1" = "/menu.lst" ] && KEYFILE1=/$OLDMENU
			setroot >>  $MENU
			case "$KBASE" in
				menu.lst)
					echo "  configfile $KEYFILE1"  >>  $MENU
					;;
				wubildr.mbr)
					echo "  chainloader $KEYFILE1"  >>  $MENU
					;;
				rootfs*) #v1.8: slitaz
					ROOTFSES=$(echo $KEYFILE| sed -e "s|,|\n$KDIR/|g" | sort -r)
					ROOTFSES=$(echo $ROOTFSES)	# replace new-lines to spaces
					P='null'
					echo "  $KERNEL $KDIR/bzImage root=/dev/$P $LINUXOPTIONS" >>  $MENU
					echo "  initrd $ROOTFSES" >>  $MENU
					;;
				core.img)
					echo "	$KERNEL $KEYFILE" >> $MENU
					;;
				grub.cfg)
					echo "	configfile $KEYFILE" >> $MENU
					;;
				easy.sfs)
					echo "  $KERNEL $KDIR/vmlinuz" >>  $MENU
					echo "  initrd $KDIR/initrd" >>  $MENU
					;;
				*.cfg)	#v1.8.9: porteus
					if [ -f "$APPTMP/$PART$KEYFILE" ]; then
						KFILE=$(grep -i 'kernel' "$APPTMP/$PART$KEYFILE"| head -n 1| sed -e 's/^.*kernel //i')
						INITRD=$(grep -i 'append' "$APPTMP/$PART$KEYFILE"| head -n 1| sed -e 's/^.*initrd=//i')
						APPEND=$(echo $INITRD| cut -d' ' -f2-)
						INITRD=$(echo $INITRD| cut -d' ' -f1)
						echo "  $KERNEL	$KDIR/$KFILE $APPEND" >>  $MENU
						echo "  initrd $KDIR/$INITRD" >>  $MENU
					else
						echo "  $KERNEL $KDIR/vmlinuz  changes=/porteus" >>  $MENU
						echo "  initrd $KDIR/initrd.xz" >>  $MENU
					fi
					;;
				initrd*)
					if [ "$UUID" ]  ; then
						ROOT="root=UUID=${UUID}"
						ROOT2="root=/dev/$PART"
					else
						ROOT="root=/dev/$PART"
					fi
					KTAIL=$(echo $KEYFILE | cut -d'-' -f2- )
					KTAIL="$KTAIL $ROOT $LINUXOPTIONS" 
					[ "$KEYFILE2" ] && KTAIL=$KEYFILE2
					if [ "$KBASE" = "initrd" ] ;then
						KTAIL=""
					#can be fatdog
						echo $LABEL | grep -qi 'fatdog' && KTAIL='rootfstype=ramfs'
					fi
						# fullinstall + initrd
						echo "  $KERNEL $KDIR/vmlinuz$KTAIL" >>  $MENU
						echo "  initrd $KDIR/$KBASE" >>  $MENU
					;;
					*) 
					echo "# '$KBASE' not supported."  >>  $MENU
					;;
			esac
			entryend >> $MENU
		done

		[ $COMPAT_MENU -eq 2 -a  "$TOREMOVABLE" ]  && ONLYIF='
if [ $grub_platform = "efi" ] ; then'

		eval WINLABEL=$(echo "$Win_0"|trim)

	if  [ $COMPAT_MENU -eq 2 ] ; then
		if [ "$TOGPT" ] || [ "$BOOTABLE_UEFI" ]  || [ "$TOREMOVABLE" ] ;then 
		# Windows
			if [ "$WINLABEL" ] ;then
				KEYFILE="/EFI/Microsoft/Boot/bootmgfw.efi"
				entrybegin "$WINLABEL uefi boot" >> $MENU
				cat <<EOF >> $MENU
	$FIND_SETROOT  $KEYFILE
	chainloader $KEYFILE
EOF
				entryend  >> $MENU
			fi
	
	#UEFI chainload
		for L in $LINEFIS; do
			debug "$L"	;#ex. sda1/EFI/ubuntu/shimx64.efi
			PART=${L%%/*}	;#ex. sda1
			KPATH="/${L#*/}"	;#ex. /EFI/ubuntu/shimx64.efi
			LABEL=$(echo $L| cut -d'/' -f3)	;#ex. ubuntu
			LABEL="$LABEL uefi boot"
			entrybegin "$LABEL" >> $MENU
			setroot >> $MENU
			echo "	chainloader $KPATH" >> $MENU
			entryend >> $MENU
		done

	#another drive
	debug "TODRIVE:$TODRIVE"
	TOPEFIS=$(echo "$TOPEFIS" | grep '/' | grep -v "$TODRIVE")
		for L in $TOPEFIS; do
			PART=${L%%/*}
			KPATH="/${L#*/}"
			LABEL="UEFI boot from $PART"
			entrybegin "$LABEL" >> $MENU
			setroot >> $MENU
			echo "	chainloader $KPATH" >> $MENU
			entryend >> $MENU
		done
		fi
	fi
	[ "$ONLYIF" ]  && ONLYIF='
if [ $grub_platform != "efi" ] ; then'

	if [ "$TOGPT" = "" ] || [  "$TOREMOVABLE" ] ;then
		if [ "$WINLABEL" ] ;then
			entrybegin "$WINLABEL mbr boot" >> $MENU
			cat <<EOF >> $MENU
	$FIND_SETROOT /bootmgr
	chainloader +1
EOF
			entryend  >> $MENU
		fi

# boot from another drive
		if [ -z "$TOREMOVABLE" ] ;then
			N=$(echo "$DRIVES" | wc -l)
			if [ $N -gt 1 ]; then
				for DRIVE in $DRIVES; do
					[ "$DRIVE" = "$TODRIVE" ]  && continue
					is_bootable $DRIVE || continue
					UUID=$(blkid /dev/$DRIVE a| cut -d' ' -f2 | cut -d'=' -f2)
					[ "$UUID" ] || continue
					LABEL=$(echo "$DISKS" | grep -w $DRIVE | cut -f3 -d'|' | tr '_' ' ')
					LABEL="Boot from $DRIVE ($LABEL)"
					#echo  >>  $MENU
					entrybegin  "$LABEL"  >>  $MENU
					#if [ "$REPLACE" != "" ];then
						#[ "$DRIVE" != "$TODRIVE" ]  && swapping $DRIVE  >>  $MENU
					#elif [ "$DRIVE" != "$FIRSTDRIVE" ]; then
						#swapping $DRIVE  >>  $MENU
					#fi
					echo "  search --no-floppy --set=root --fs-uuid $UUID" >> $MENU
					echo "  chainloader +1"  >>  $MENU
					entryend  >> $MENU
				done
			fi
		fi
		fi	

		ONLYIF='
if [ $grub_platform = "efi" ] ; then'
		entrybegin  "UEFI Firmware Settings"  >>  $MENU
		echo '	fwsetup'  >>  $MENU
		entryend  >> $MENU

	ONLYIF=""

	# custom menu
	if [ $COMPAT_MENU -eq 2 ] ;then
		if [ ! -f $TOPDIR/custom.cfg ] ;then
			cat <<EOF >>$TOPDIR/custom.cfg
# You can add custom menu entry here.
#Example:
#menuentry "My Puppy"{
#		search --set=root --no-floppy --file /mypuppy/vmlinuz
#		linux /mypuppy/vmlinuz psubdir=mypuppy pmedia=atahd pfix=fsck
#		initrd /mypuppy/initrd.gz
#	}
# $APPNAME does nor rewrite this file.
EOF
		fi
		cat <<EOF >>$MENU

	# custom menu
	if [ -f /custom.cfg ] ;then source /custom.cfg ;fi
EOF
	else
	# Grub4Dos
		if [ ! -f $TOPDIR/custom.lst ] ;then
			cat <<EOF >>$TOPDIR/custom.lst
# You can add custom (grub4dos) menu here.
#Example:
#title My Puppy
#		find --set=root --no-floppy --file /mypuppy/vmlinuz
#		kernel /mypuppy/vmlinuz psubdir=mypuppy pmedia=atahd pfix=fsck
#		initrd /mypuppy/initrd.gz
#
# $APPNAME does nor rewrite this file.
EOF
		fi
		cat <<EOF >>$MENU

	# custom menu
	title Custom menu
		configfile /custom.lst
EOF
	fi
	
	# old menu
	if [ "$OLDMENU" ]; then
		entrybegin "Previous  menu" >> $MENU
		echo "	configfile /$OLDMENU" >> $MENU
		entryend >> $MENU
	fi

	sync
	echo "Writing menu completed." >>$MYLOG

	fi ### skip menu end

#====================== install boot loader =========================	

	whereto_check

file_size() {
	[ "$1" ] || exit 1
	[ -f "$1" ] || exit 1
	ls -l "$1" | cut -d' ' -f5
}

	if  [ "$KEEP_BOOT_RECORD" = "true" ] ;then
		echo "Skipping boot loader install." >>$MYLOG
	else
		mountpoint $LPART || fatal "Failed mounting:$LPART"
		TOPDIR=$MP
		debug "TOPDIR:$TOPDIR"
		#BOOTLOADR="grub2"
		####################### uefi stuff
		if [ "$UEFI_INSTALL" = 'true' ]  ; then
				BOOTSTYLE='UEFI'
				ARCHIVE="grub2pup-efi.tar.xz"
				D=$APPLIBDIR
				[ -f  "$D/$ARCHIVE" ] && ARCHIVE="$D/$ARCHIVE" || error_missing --fatal "$APPLIBDIR$ARCHIVE" 
				debug  "Extracting $ARCHIVE..."
					BOOT=""
				BOOTX=""
				BOOTBAK=""
				echo "Installing $BOOTSTYLE bootloader on /dev/$WHERETO, $TOPDIR ..." >>$MYLOG
				tar -vxf "$ARCHIVE" --overwrite --exclude='*32.efi' -C "$TOPDIR" >>$MYLOG 2>&1 || fatal "Faild to expand '$ARCHIVE'."
				# buckup bootx
				 [ -d "$TOPDIR/EFI" ]  && BOOTS=$(find -L "$TOPDIR/EFI" -maxdepth 1 -iname "boot" -type d)
				for BOOT in $BOOTS ;do
					BOOTBAK="$BOOT.bak"
					rm -fr "$BOOTBAK"
					mv "$BOOT" "$BOOTBAK"
				done
				EFIPUPPY="$TOPDIR/EFI/Puppy"
				cp -vr $EFIPUPPY "$TOPDIR/EFI/boot" >> $MYLOG 2>&1
				if [ -z "$TOREMOVABLE" ] ;then
					EFI_DEVICE="$WHERETO"
					# v2.0.2: add test for mmcblk/nvme EFI partitions
					[ $(echo "$BOOTPART" | grep -E 'mmcblk|nvme') ] && \
					EFI_PARTITION=$(echo $BOOTPART | cut -d'p' -f2) || \
					EFI_PARTITION=$(echo $BOOTPART | cut -c 4-)
					# delete any previous boot
					pupNum="$(efibootmgr | grep 'Puppy Linux' | cut -b5-8)"
					if [ "$pupNum" ] ;then
							efibootmgr -b $pupNum -B >>$MYLOG 2>&1 || fatal "Failed to delete previous boot"
					fi
					# register new boot
					efibootmgr -c -d /dev/$EFI_DEVICE -p $EFI_PARTITION -l '\EFI\Puppy\bootx64.efi' -L "Puppy Linux - Grub2" >>$MYLOG 2>&1 || fatal "Failed to register Puppy boot loader."
				fi
		fi
		####################### MBR boot stuff
		if [ "$MBR_INSTALL" = 'true' ] ;then
				BOOTSTYLE='MBR'
			  #--- grub2 stuff
				ARCHIVE="$APPLIBDIR/grub2pup-mbr.tar.xz"
				[ -f  "$ARCHIVE" ]  || error_missing --fatal "$ARCHIVE" 
				debug  "Expanding $ARCHIVE..."
				echo "Installing $BOOTSTYLE bootloader on /dev/$WHERETO, $TOPDIR ..." >>$MYLOG
				tar -xf "$ARCHIVE" --overwrite -C "$TOPDIR" >>$MYLOG 2>&1 || fatal "Faild to expand '$ARCHIVE'."
				MBRBAK=""
				if [ "$BOOTABLE_MBR" ]  ;then
					dd if=/dev/$WHERETO of=/tmp/$WHERETO.mbr count=$BSIZE_MBR >>$MYLOG 2>&1 && MBRBAK="$WHERETO.mbr"
				fi
				echo "Installing Grub2 initial boot loader to /dev/$WHERETO MBR..." >>$MYLOG
				GRUB2MBR="$APPLIBDIR/grub2.mbr"
				[ -f "$GRUB2MBR" ] || error_missing --fatal "$GRUB2MBR" 
				dd bs=446 count=1 if="$GRUB2MBR" of=/dev/$WHERETO >>$MYLOG 2>&1 || fatal "Failed to install grub2 to /dev/$WHERETO MBR"
				dd bs=2 count=1 seek=255  skip=255 if="$GRUB2MBR" of=/dev/$WHERETO >>$MYLOG 2>&1 || fatal "Failed to install grub2 to /dev/$WHERETO MBR"
				dd seek=1  skip=1 if="$GRUB2MBR" of=/dev/$WHERETO >>$MYLOG 2>&1 || fatal "Failed to install grub2 to /dev/$WHERETO MBR"
				echo "Finished writing grub2 initial boot loader to the MBR." >>$MYLOG
				if [ "$MBRBAK" ] ;then
					KFREE=$(kbyte_free "$TOPDIR")
					# kB is 2x512bytes
					if [ $(($KFREE + $KFREE)) -ge $BSIZE_MBR ]; then
						MBRBAK=""
						echo "Making backup of the MBR(/dev/${WHERETO}) ..." >>$MYLOG
						cp -vf /tmp/$WHERETO.mbr $TOPDIR/${WHERETO}_mbr.bak >>$MYLOG 2>&1 && MBRBAK="$TOPDIR/${WHERETO}_mbr.bak"
					else
						echo "'/tmp/$WHERETO.mbr' is not copied to '$TOPDIR' because of no space."  >>$MYLOG
					fi
				fi
		fi
		sync
		echo "Boot loader successfully installed.">>$MYLOG
		################ end of  installing boot loaders
	fi

splash end
#========================== finish =================================
_BootLoaderInstalled=$(gettext "Boot loader successfully installed.")
_MenuInstalled=$(gettext "Menu successfully installed.")
_EditMenu=$(gettext "Edit menu")

whereto_check
echo -e "All finished." >> $MYLOG

MSG=$_BootLoaderInstalled
 [ "$KEEP_BOOT_RECORD" = 'true' ]  && MSG=$_MenuInstalled

DIALOG="<window title=\"$CREDIT - Success\"><vbox>
$WHERETO_FRAME
 <frame>
 <hbox><pixmap icon_size=\"4\"><input file stock=\"gtk-apply\"></input></pixmap>
 <text space-expand=\"true\" space-fill=\"true\"><input>echo -en \"$MSG\"</input></text></hbox>
  </frame>
  <hbox>
    "$(make_help_button "editmenufile")"
    <button><input file stock=\"gtk-edit\"></input>
    <label>\"$_EditMenu\"</label><action>defaulttexteditor $MENU &</action></button>
    <button><input file stock=\"gtk-edit\"></input><label>$(gettext 'See log')</label>
   <action>defaulttextviewer $MYLOG &</action></button>
   </hbox>
  <text><label>$_Quit</label></text>
  <hbox>
   <button ok></button>
  </hbox>
  </vbox></window>"  
$GTKDIALOG -p DIALOG -c &>/dev/null

umountmine
rm -f $MYLOG
exit 0

### END ###
