#!/bin/bash
# -*- ENCODING: UTF-8 -*-

# pica-ie
#
# Install to external (removable) device.
#
# Copyright (c) 2013-2026: Alexis Puente Montiel   < pica (a) picalibre.org >
#
# Licensed according to GNU AGPL version 3.0.
#
# It is libre/free software; you can use, redistribute and/or modify it according to the terms of GNU AGPL as published by GNU, version 3.0, 19 November 2007.
#
# It is distributed in the hope that it will be useful, but without any warranty. Read GNU AGPL version 3.0 for additional details.
#
# A copy of GNU AGPL version 3.0 is available at /usr/share/doc/<software-package-name>/agpl-3.0.txt (additionally on Internet as text at https://www.gnu.org/licenses/agpl-3.0.txt and as HTML at https://www.gnu.org/licenses/agpl-3.0-standalone.html ).
#
# Note: Additionally to the official e-mails, picalibre.org is strictly the only official site for this software project, please consider using it to download, report bugs and contribute.
#
# Depends: bash, coreutils, dialog | yad | yad-pica | zenity, dosfstools, dpkg, findutils, gawk | mawk | original-awk, gddrescue, grep, lsof, mount | pmount, procps, sed, util-linux
# Recommends: bc, e2fsprogs, lxterminal | sakura | xfce4-terminal, menu, parted, pica-skel, util-linux (<<2.29.2-3) | fdisk, x11-xkb-utils
# Suggests: 7zip | p7zip-full | unar | zstd, gparted | partitionmanager, libdigest-sha3-perl, libdigest-whirlpool-perl, rhash


### SCRIPT VARIABLES ########################################

CNAME="pica-ie"
VERSION="1.3.1"
TITLE="Pica-IE"
ICON="/usr/share/icons/pica-ie.png"

# Location of dependent lib files
LIBDEP=/usr/share/$CNAME

# Translations
if [ "$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=pica-ie
TEXTDOMAINDIR=/usr/share/locale/

# Write errors to log
ERRORLOG="$HOME/.${CNAME}.log"
if [ -e "$ERRORLOG" ] ; then
	mv -f $ERRORLOG ${ERRORLOG}.ant
fi
if [ -e "$ERRORLOG" ] ; then rm -rf "$ERRORLOG" ; fi

for i in /etc/pica-global.dist /etc/pica-global.orig /etc/pica-global /etc/pica-global.local ~/.pica-global ~/pica-global ; do
	if [ -f "$i" ] ; then
	cat "$i"
	source "$i"
	source <(cat $i | sed -e "s/=\(YES\|Yes\|yes\|y\|SÍ\|SI\|Sí\|Si\|sí\|si\|S\|s\)/=Y/g" -e "s/=\(No\|no\|n\)/=N/g" -e "s/=\"\(YES\|Yes\|yes\|y\|SÍ\|SI\|Sí\|Si\|sí\|si\|S\|s\)\"/=Y/g" -e "s/=\"\(No\|no\|n\)\"/=N/g")
	fi
done
if [ "$DEBUG" = "Y" ] ; then
	set -xv
	DEBUG="Y"
else
	ERRORLOG="/tmp/.${CNAME}_$(id -nu).log"
	if [ -e "$ERRORLOG" ] ; then mv -f $ERRORLOG ${ERRORLOG}.ant ; fi
	if [ -e "$ERRORLOG" ] ; then rm -rf "$ERRORLOG" ; fi
fi
#if [ "$DEBUG" = "" ] ; then DEBUG="N" ; fi
if [ "$DEBUG" != "N" ] ; then
exec > >(tee -a "$ERRORLOG") 2>&1
echo "$0" "$*" >> "$ERRORLOG"
echo "$CNAME" "$VERSION" >> "$ERRORLOG"
echo $(date +%Y-%m-%d_%H:%M:%S) $"Start" >> "$ERRORLOG"
echo "env:" >> "$ERRORLOG"
env >> "$ERRORLOG"
echo "set:" >> "$ERRORLOG"
set >> "$ERRORLOG"
#else
#exec 2>>"$ERRORLOG"
fi

# Description:
BDESCRIP=$"Install to external (removable) device."
LDESCRIP=$"$TITLE is a tool to install to a SD card or USB device from an IMG/ISO/RAW file or from a live system."

# Documentation:
docu_info () {
echo "$CNAME ($VERSION) - $BDESCRIP"
echo 
echo $"Usage:" $CNAME [$"OPTIONS"]
echo 
echo $"Options:"
echo -e "$ODESCRIP"
echo 
echo $"'man $CNAME' for more information."
echo 
}
ODESCRIP=" -t""\t"$"Use terminal interface.""\n"" -k""\t"$"Use 'kdialog' if possible.""\n"" -y""\t"$"Use 'yad' if possible (by default in graphical sessions).""\n"" -z""\t"$"Use 'zenity' if possible.""\n"" -x""\t"$"Show help documentation."

while getopts tkyzx OPTION ; do
	case $OPTION in
		t )   T="Y" ; G="N"      ;;
		k )   SDIALOG="kdialog"  ;;
		y )   SDIALOG="yad"      ;;
		z )   SDIALOG="zenity"   ;;
		x )   docu_info ; exit 0 ;;
	esac
done


### DIALOG ########################################

#DEFAULTDIALOGLIST="yad zenity kdialog"
DEFAULTDIALOGLIST="yad zenity"

#if [ -t 0 ] ; then
if [ "$(setxkbmap 1>/dev/null 2>&1 ; echo $? )" -ne 0 ] ; then
	G="N" ; T="Y"
fi

if [ "$G" != "N" ] ; then
	
	if   [ "$SDIALOG" = "kdialog" ] ; then
		DIALOGLIST="kdialog yad zenity"
	elif [ "$SDIALOG" = "yad" ] ; then
		DIALOGLIST="yad zenity kdialog"
	elif [ "$SDIALOG" = "zenity" ] ; then
		DIALOGLIST="zenity yad kdialog"
	else
		DIALOGLIST="$DEFAULTDIALOGLIST"
	fi
	
	if [ "$DIALOGLIST" = "" ] ; then
		if [ "$DEFAULTDIALOGLIST" != "" ] ; then
			DIALOGLIST="$DEFAULTDIALOGLIST"
		else
			DIALOGLIST="yad zenity kdialog"
		fi
	fi
	
	if [ "$(command -v $DIALOGLIST)" = "" ] ; then
		G="N" ; T="Y"
	fi

fi


if [ "$G" = "N" ] ; then

	if [ "$(command -v dialog)" = "" ] ; then
		echo $"ERROR: No supported dialog is installed. $TITLE cannot continue."
		exit 1
	else
		
		DIALOG="dialog --cr-wrap --keep-window --output-fd 1"
		#DIALOG="dialog --cr-wrap --keep-window --output-fd 1 --no-lines --no-shadow"
		if [ "$TITLE" != "" ] ; then
			WICON="--backtitle $(echo $TITLE | sed 's| |-|g')"
		fi
		WTITLE="--title"
		WTEXT=""
		H="0"
		W="0"
		LH="0"
		CALENDAR="--calendar"
		DATEFORMAT="--date-format %Y-%m-%d"
		WTIME="--timebox"
		TIMEFORMAT="--time-format %H:%M:%S"
		DSEL="--dselect"
		FSEL="--fselect"
		WRITE="--inputbox"
		PREWRITE=""
		COLUMN=""
		PRINTCOLUMN1=""
		PRINTCOLUMN2=""
		HIDECOLUMN1=""
		HIDECOLUMN2=""
		#INPUTSEPARATOR="--column-separator"
		#OUTPUTSEPARATOR="--separate-output"
		MONOLIST="--menu"
		#MONOLIST="--radiolist"
		MULTIPLELIST="--separate-output --checklist"
		PRE=""
		POST="off"
		PRES=""
		POSTS="on"

		INFO="--msgbox"
		WAIT="--infobox"

		QYN="--yesno"
		QYNC="--yesno"
		WYN="--yesno"
		WCC="--yesno"
		WYNC="--yesno"
		WM="--msgbox"
		ERROR="--msgbox"

		FORM="--form"
		FORMT=""
		FORMSELPRE=""
		FORMSELPOST=""
		#FORMCALPRE=""
		#FORMCALPOST=""
		#FORMCLPRE=""
		#FORMCLPOST=""
		PRELAB1="1 1"
		POSTLAB1="1 10 999 0"
		PRELAB2="2 1"
		POSTLAB2="2 10 999 0"
		PRELAB3="3 1"
		POSTLAB3="3 10 999 0"

		YES="--yes-label"
		NO="--no-label"
		OK="--ok-label"
		CONTINUE="--ok-label"
		CANCEL="--cancel-label"
		EXTRABUTTON="--extra-button --extra-label"
	
	fi

else

	for i in $DIALOGLIST ; do

		if [ "$(command -v $i)" != "" ] ; then
	
			if [ "$i" = "yad" ] ; then
		
				if [ "$(yad --version | tail -n 1 | cut -d ' ' -f 1 | cut -d '.' -f 1)" -lt 2 ] ; then
					DIALOG="yad --center"  # --selectable-labels (bug in Yad < 2.0) https://github.com/v1cont/yad/blob/master/NEWS
				else
					DIALOG="yad --center --selectable-labels"  # --on-top
				fi
				if [ "$ICON" != "" ] ; then
					WICON="--window-icon $ICON"
				fi
				WTITLE="--title"
				WTEXT="--text"
				H=""
				if [ "$(yad --version | tail -n 1 | grep -aE ^'7.2')" != "" ] ; then
					W="--width=640"
				else
					W="--width=640 --text-width=640 --fixed"  # https://github.com/v1cont/yad/issues/107  https://github.com/v1cont/yad/issues/140
				fi
				LH=""
				CALENDAR="--calendar"
				DATEFORMAT="--date-format %Y-%m-%d"
				WTIME="--separator=\n --columns 3 --form"
				#TIMEFORMAT="--time-format %H:%M:%S"
				DSEL="--file --directory --filename"  # Deleted *-selection alias for --file in Yad 4.0
				FSEL="--file --filename"              # Deleted *-selection alias for --file in Yad 4.0
				WRITE="--entry"
				PREWRITE="--entry-text"
				COLUMN="--column="
				PRINTCOLUMN1="--print-column=01"
				PRINTCOLUMN2="--print-column=02"
				HIDECOLUMN1="--hide-column=01"
				HIDECOLUMN2="--hide-column=02"
				#INPUTSEPARATOR="--item-separator"
				#OUTPUTSEPARATOR="--separator="
				#MONOLIST="--entry"
				MONOLIST="--separator=\n --list --search-column=1 --no-headers"
				MONOLISTH="--separator=\n --list --search-column=1"
				MULTIPLELIST="--separator= --list --checklist --search-column=2 --no-headers"
				MULTIPLELISTH="--separator= --list --checklist --search-column=2"
				PRE="FALSE"
				POST=""
				PRES="TRUE"
				POSTS=""
				# standard gtk keybindings for next and previous search are ctrl+g and ctrl+shift+g while you can redefine them in gtk-keys.css for your theme  # https://github.com/v1cont/yad/issues/127
			
				INFO="--image=/usr/share/icons/picalibre/rm/play.png --button="$"OK"
				WAIT="--image=/usr/share/icons/picalibre/rm/play.png --no-buttons"
			
				QYN="--image=/usr/share/icons/picalibre/rm/question.png --button="$"Yes"":0 --button="$"No"":1"
				QYNC="--image=/usr/share/icons/picalibre/rm/question.png --button="$"Yes"":0 --button="$"No"":1 --button="$"Cancel"":1"
				WYN="--image=/usr/share/icons/picalibre/rm/warning.png --button="$"Yes"":0 --button="$"No"":1"
				WCC="--image=/usr/share/icons/picalibre/rm/warning.png --button="$"Continue"":0 --button="$"Cancel"":1"
				WYNC="--image=/usr/share/icons/picalibre/rm/warning.png --button="$"Yes"":0 --button="$"No"":1 --button="$"Cancel"":1"
				WM="--image=/usr/share/icons/picalibre/rm/warning.png --button="$"OK"
				ERROR="--image=/usr/share/icons/picalibre/rm/error.png --button="$"OK"
			
				FORM="--separator=\n --form"
				FORMT="--field"
				FORMSELPRE="--field"
				FORMSELPOST=":FL"
				FORMCALPRE="--field"
				FORMCALPOST=":DT"
				FORMCLPRE="--field"
				FORMCLPOST=":CB"
				PRELAB1=""
				POSTLAB1=""
				PRELAB2=""
				POSTLAB2=""
				PRELAB3=""
				POSTLAB3=""
			
				YES="--button"
				NO="--button"
				OK="--button"
				CONTINUE="--button"
				CANCEL="--button"
				EXTRABUTTON="--button"
		
			elif [ "$i" = "zenity" ] ; then
		
				DIALOG="zenity"
				if [ "$ICON" != "" ] ; then
					WICON="--window-icon $ICON"
				fi
				WTITLE="--title"
				WTEXT="--text"
				H=""
				W="--width=640"
				LH=""
				CALENDAR="--calendar"
				DATEFORMAT="--date-format %Y-%m-%d"
				WTIME="--separator : --forms"
				#TIMEFORMAT="--time-format %H:%M:%S"
				DSEL="--file-selection --directory --filename"
				FSEL="--file-selection --filename"
				WRITE="--entry"
				PREWRITE="--entry-text"
				COLUMN="--column="
				PRINTCOLUMN1="--print-column=01"
				PRINTCOLUMN2="--print-column=02"
				HIDECOLUMN1="--hide-column=01"
				HIDECOLUMN2="--hide-column=02"
				#INPUTSEPARATOR=""
				#OUTPUTSEPARATOR="--separator=\n"
				MONOLIST="--separator=\n --list --hide-header"
				MONOLISTH="--separator=\n --list"
				MULTIPLELIST="--separator=\n --list --checklist --hide-header"
				MULTIPLELISTH="--separator=\n --list --checklist"
				PRE="FALSE"
				POST=""
				PRES="TRUE"
				POSTS=""
			
				INFO="--info"
				WAIT="--info"
			
				QYN="--question"
				QYNC="--question"
				WYN="--question"
				WCC="--question"
				WYNC="--question"
				WM="--warning"
				ERROR="--error"
			
				FORM="--forms"
				FORMT="--add-entry"
				FORMSELPRE="--add-entry"
				FORMSELPOST=""
				FORMCALPRE="--add-calendar"
				FORMCALPOST=""
				if [ "$(zenity --version | cut -d '.' -f 1 )" -ge 3 ] || [ "$(zenity --version | sed 's|\.||g')" -ge 3102 ] ; then
					FORMCLPOST="--combo-values"
					FORMCLPRE="--add-combo"
				fi
				PRELAB1=""
				POSTLAB1=""
				PRELAB2=""
				POSTLAB2=""
				PRELAB3=""
				POSTLAB3=""
			
				# Zenity <3 does not support custom buttons.
				if [ "$(zenity --version | cut -d '.' -f 1 )" -ge 3 ] ; then
					YES="--ok-label"
					NO="--cancel-label"
					OK="--ok-label"
					CONTINUE="--ok-label"
					CANCEL="--cancel-label"
					#EXTRABUTTON=""
				fi
		
#			elif [ "$i" = "kdialog" ] ; then
#		
#				# CAUTION: All 'kdialog' (TDE, KDE Plasma 4, KDE Plasma 5, KDE Plasma 6,...) are included here!
#			
#				DIALOG="kdialog"
#				if [ "$ICON" != "" ] ; then
#					WICON="--icon $ICON"
#				fi
#				WTITLE="--title"
#				WTEXT=""
#				H=""
#				W=""
#				LH=""
#				# No "--calendar" in TDE-kdialog + No "--date-format" both TDE and Plasma = There is no usable version of kdialog for calendars
#				#CALENDAR="--calendar"
#				#DATEFORMAT="--date-format %Y-%m-%d"
#				#WTIME="--timebox"
#				#TIMEFORMAT="--time-format %H:%M:%S"
#				DSEL="--getexistingdirectory"
#				FSEL="--getsavefilename"
#				#FSEL="--getopenfilename"
#				WRITE="--inputbox"
#				PREWRITE=""
#				COLUMN=""
#				PRINTCOLUMN1=""
#				PRINTCOLUMN2=""
#				HIDECOLUMN1=""
#				HIDECOLUMN2=""
#				#INPUTSEPARATOR=""
#				#OUTPUTSEPARATOR="--separate-output"
#				MONOLIST="--menu"
#				#MONOLIST="--combobox"
#				#MONOLIST="--radiolist"
#				MULTIPLELIST="--separate-output --checklist"
#				PRE=""
#				POST="off"
#				PRES=""
#				POSTS="on"
#			
#				INFO="--msgbox"
#				WAIT="--msgbox"
#			
#				QYN="--yesno"
#				QYNC="--yesnocancel"
#				WYN="--warningyesno"
#				WCC="--warningcontinuecancel"
#				WYNC="--warningyesnocancel"
#				WM="--sorry"
#				ERROR="--error"
#			
#				# No "--form" in any kdialog version
#				#FORM="--form"
#				#FORMT=""
#				#FORMSELPRE=""
#				#FORMSELPOST=""
#				#FORMCALPRE=""
#				#FORMCALPOST=""
#				#FORMCLPRE=""
#				#FORMCLPOST=""
#				#PRELAB1=""
#				#POSTLAB1=""
#				#PRELAB2=""
#				#POSTLAB2=""
#				#PRELAB3=""
#				#POSTLAB3=""
#			
#				# TDE-kdialog does not support custom buttons.
#				if [ "$(kdialog --version | grep -a Qt | grep -aEo "[0-9]" | head -n 1)" -ge 4 ] || [ "$(kdialog --version | grep -aEi kdialog | grep -aEo "[0-9]" | head -n 1)" -gt 1 ] ; then
#					YES="--yes-label"
#					NO="--no-label"
#					OK="--continue-label"
#					CONTINUE="--continue-label"
#					CANCEL="--cancel-label"
#					EXTRABUTTON="--cancel-label"
#				fi
		
			else
		
				true
		
			fi
		
		if [ "$DIALOG" != "" ] ; then break ; fi
		
		fi

	done

fi

if [ "$DIALOG" = "" ] ; then
	echo $"ERROR: No supported dialog is installed. $TITLE cannot continue."
	exit 1
fi


### TERMINAL SELECTION ########################################

if [ "$G" != "N" ] && [ "$(command -v lxterminal sakura xfce4-terminal)" = "" ] ; then $DIALOG $WICON $WTITLE "$TITLE" $WM    $WTEXT $"WARNING: Neither 'lxterminal', nor 'sakura' nor 'xfce4-terminal' are installed, $TITLE might fail." $H $W ; fi

TERMINAL () {
if [ "$G" = "N" ] ; then
	if [ "$TT" != "$TITLE" ] ; then echo "$TT" ; sleep 1 ; fi
	$COM
else
	if [ "$(command -v sakura)" != "" ] ; then
#		sakura -t "$TT" -e "$COM"  # https://bugs.debian.org/782396
		sakura -t "$TT" -x "$COM"  # sakura '-e' bug en Debian 13 "Trixie": Segment violation
	elif [ "$(command -v lxterminal)" != "" ] ; then
		lxterminal -t "$TT" -e "$COM"
	elif [ "$(command -v xfce4-terminal)" != "" ] ; then
		xfce4-terminal -T "$TT" -e "$COM"
	else
		x-terminal-emulator -t "$TT" -e "$COM"
	fi
fi
}


### ROOT CHECK ########################################

##if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -ne 0 ] ; then
#if [ "$(id -u)" -ne 0 ] ; then
#	$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"$TITLE must be launched as SuperUser.\n\nCannot continue." $H $W
#	exit 1
#fi
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/trinity/bin

## SuperUser must NOT run this script
## if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
#if [ "$(id -u)" -eq 0 ] ; then
#	$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"$TITLE must be launched by normal user (not SuperUser)."  $H $W
#	exit 1
#fi


### BASICFUN ########################################

ESP=$(printf '\302\240')

clean () {

	if [ "$DCTMP" != "$ISODIR" ] && [ "$DCTMP" != "/tmp" ] && [ "$DCTMP" != "$HOME" ] ; then
		if [ -e "$DCTMP" ] ; then
			rm -rfv "$DCTMP"
		fi
	fi

}

check_exit () {

TAILERRORLOG=$(cat "$ERRORLOG" | grep -aE "[a-zA-Z0-9\=\[]" | tail -n 10 )

echo $(date +%Y-%m-%d_%H:%M:%S)

clean

#if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
if [ "$(id -u)" -eq 0 ] && [ "$DEBUG" = "Y" ] ; then
	RECERRORLOG="$ERRORLOG"
	for i in $(cat /etc/passwd | awk -F ':' '{print $3,$1}' | sort -n | grep -aEi "00[0-9] " | awk '{print $2}') ; do AUSER=$(users | sed 's| |\n|g' | grep -aE "^$i$" | head -n 1) ; if [ "$AUSER" != "" ] ; then
		HOMEERRORLOG=/home/$i/.${CNAME}.log
		RECERRORLOG="$RECERRORLOG $HOMEERRORLOG "
		cp -v --remove-destination $ERRORLOG $HOMEERRORLOG
		if [ "$(id -nu $i)" != "" ] ; then chown $(id -nu $i):$(id -ng $i) $HOMEERRORLOG ; else chown 1000:1000 $HOMEERRORLOG ; fi
		chmod 600 $HOMEERRORLOG ; if [ "$(stat -c %U $HOMEERRORLOG)" != "$i" ] ; then chmod 666 $HOMEERRORLOG ; fi
		break
	fi ; done
fi

$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"Stop due to error.\n\n$TAILERRORLOG\n" $H $W

exit 1

}

# "try again or exit" dialog window
input_error () {

echo $(date +%Y-%m-%d_%H:%M:%S)

$DIALOG $WICON $WTITLE "$TITLE" $WYN   $WTEXT $"Something went wrong.\n\nDo you want to try again?" $H $W

if [ "$?" -ne 0 ] ; then
	clean
	exit 1
else
	$REFUN
fi

}


### ALREADY RUNNING ########################################

if [ "$CNAME" != "" ] && [ "$(lsof /usr/bin/$CNAME 2>>$ERRORLOG | grep -ai -c $CNAME)" -gt 1 ] ; then

	REPE=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"$CNAME seems to be already working. Having $CNAME working multiple times at the same time may cause problems.\n\nStop them all is recommended.\n\nPlease select an option:" $H $W $LH $COLUMN $COLUMN \
	$"Continue" " " \
	$"Stop now" " " \
	$"Stop them all" " " \
	| head -n 1 )

	if [ "$?" -ne 0 ] || [ "$REPE" = "" ] ; then
		exit 0
	fi

	case $REPE in

		$"Continue" )
			true
		;;

		$"Stop now" )
			exit 0
		;;

		$"Stop them all" )
			clean
			kill $(echo $(ps aux | grep -a "$CNAME" | grep -av 'grep ' | awk '{print $2}'))
		;;

	esac

fi


### WELCOME ########################################

if [ "$WELCOME" != "N" ] ; then

$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"Welcome to $TITLE.\n\n$TITLE is a tool to install to a SD card or USB device from an IMG/ISO/RAW file or from a live system.\n\n$TITLE is libre/free software, licensed according to 'GNU AGPL version 3.0'.\n\nIt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.\n\nMore information at www.picalibre.org\n" $H $W

if [ "$?" -ne 0 ] ; then
	exit 0
fi

fi


$DIALOG $WICON $WTITLE "$TITLE" $WYN   $WTEXT $"All the content of the SD card or USB device will be ERASED. Please copy the existing files (documents, photos,...) on the SD card or USB device that you want to keep to another disk before continuing.\n\nDo you want to continue?\nPlease cancel if you don't want to do it! \n" $H $W

if [ "$?" -ne 0 ] ; then
	exit 0
fi


### SEL ########################################

sel_opt () {

OPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Please select an option (if in doubt, select from an IMG/ISO/RAW file):" $H $W $LH $COLUMN $COLUMN \
"I " $"From an IMG/ISO/RAW file" \
"L " $"From a live session" \
"X " $"Stop now" \
| head -n 1 )

if [ "$?" -ne 0 ] || [ "$OPT" = "" ] ; then
	exit 0
fi

if [ "$(echo $OPT | grep -a 'X' )" != "" ] ; then
	exit 0
fi

}

sel_opt


### IMG/ISO/RAW ########################################

if [ "$(echo $OPT | grep -a 'I' )" != "" ] ; then

## IMG/ISO/RAW file composed of two parts?
#$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Is it a IMG/ISO/RAW file composed of two parts?\n\n(If in doubt, select 'No/Cancel'.)" $H $W
#if [ "$?" -eq 0 ] ; then
#	ISO2P="Y"
#	ISO2PTEXT=$"(select the first part first)"
#else
#	ISO2P="N"
#	ISO2PTEXT=""
#fi

# Check checksum
checksum_seliso () {

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Do you want to check the IMG/ISO/RAW file? \n\nIt is highly recommended.\nTo do it, you must have got a checksum and corresponding checksum signature from the same site as the IMG/ISO/RAW file.\nFor example a file with a name similar to b2sum.txt, sha256sum.txt, sha512sum.txt or sha3sum.txt plus another associated file with a name similar to b2sum.txt.ext.ccr, b2sum.txt.ext.gpg, sha256sum.txt.ext.ccr, sha256sum.txt.ext.gpg, sha512sum.txt.ext.ccr, sha512sum.txt.ext.gpg, sha3sum.txt.ext.ccr or sha3sum.txt.ext.gpg. Only one of each, a checksum file and an associated signature file, are required.\n" $H $W

if [ "$?" -eq 0 ] ; then

	$DIALOG $WICON $WTITLE "$TITLE" $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
	PIDDIALOGEXPORT=$( echo $! )
if [ "$GPGIMPORT" != "N" ] && [ "$(command -v gpg )" != "" ] ; then
	ls /usr/share/keyrings/ | grep -aEi 'gpg|gnupg|pgp' | grep -aEiv 'removed|deleted|obsoleted|deprecated' | while read i ; do gpg --import /usr/share/keyrings/$i ; done
	STEST=$( expr $(stat -c "%s" "$HOME/.gnupg/pubring.gpg~") / $(stat -c "%s" "$HOME/.gnupg/pubring.gpg") ) ; if [ "$STEST" -gt 4 ] ; then cp -a --remove-destination "$HOME/.gnupg/pubring.gpg~" "$HOME/.gnupg/pubring.gpg" ; fi
fi
if [ "$CCRIMPORT" != "N" ] && [ "$(command -v ccr )" != "" ] ; then
	ls /usr/share/keyrings/ | grep -aEi 'ccr|codecrypt' | grep -aEiv 'removed|deleted|obsoleted|deprecated' | while read i ; do ccr --import -y --in /usr/share/keyrings/$i ; done
	STEST=$( expr $(stat -c "%s" "$HOME/.ccr/secrets~") / $(stat -c "%s" "$HOME/.ccr/secrets") ) ; if [ "$STEST" -gt 4 ] ; then cp -a --remove-destination "$HOME/.ccr/secrets~" "$HOME/.ccr/secrets" ; fi
	STEST=$( expr $(stat -c "%s" "$HOME/.ccr/pubkeys~") / $(stat -c "%s" "$HOME/.ccr/pubkeys") ) ; if [ "$STEST" -gt 4 ] ; then cp -a --remove-destination "$HOME/.ccr/pubkeys~" "$HOME/.ccr/pubkeys" ; fi
fi
	kill $PIDDIALOGEXPORT 2>/dev/null

cat > /tmp/${CNAME}_sum <<EOF
#!/bin/bash

CNAME=$CNAME
VERSION=$VERSION
TITLE=$TITLE

# Translations
if [ "\$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=$TEXTDOMAIN
TEXTDOMAINDIR=$TEXTDOMAINDIR

ERRORLOG="$ERRORLOG"
if [ "$DEBUG" = "Y" ] ; then
	set -xv
fi
if [ "$DEBUG" != "N" ] ; then
exec > >(tee -a "\$ERRORLOG") 2>&1
echo "\$0" "\$*" >> "\$ERRORLOG"
fi

################################

ISONAME="$ISONAME"
ISODIR="$ISODIR"

cd "\$ISODIR"

if [ -e /tmp/pica-ie_sum-res ] ; then
	rm -f /tmp/pica-ie_sum-res
fi

#rm -rf /tmp/pica-ie-gpg_0 /tmp/pica-ie-gpg_1

SIGTEST=\$(ls "\$ISODIR" | grep -aEi "\.gpg$|\.pgp$|\.gnupg$|\.sig$|\.asc$|\.ccr$|\.codecrypt$" | grep -a -c ^)
if [ "\$SIGTEST" -ge 1 ] ; then
	true
else
	echo " "
	echo -e "\e[1;31m"$"ERROR:"" "$"No signature detected.""\e[0m" | tee -a /tmp/pica-ie_sum-res
	echo " "
	echo $"Press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to continue."
	echo " "
	read KEY
fi

if [ "\$SIGTEST" -ge 1 ] ; then
ls "\$ISODIR" | grep -aEi "\.gpg$|\.pgp$|\.gnupg$|\.sig$|\.asc$|\.ccr$|\.codecrypt$" | while read i ; do
	if   [ "\$(echo "\$i" | grep -aEi "\.int\.gpg$|\.int\.pgp$|\.int\.gnupg$|\.int\.sig$|\.int\.asc$")" != "" ] ; then
		SEL="\$i"
		gpg --verify "\$SEL"
		if [ "\$?" -ne 0 ] ; then
			echo " "
			echo -e "\$SEL"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		else
			echo " "
			echo -e "\$SEL"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		fi
	elif [ "\$(echo "\$i" | grep -aEi "\.gpg$|\.pgp$|\.gnupg$|\.sig$|\.asc$")" != "" ] ; then
		SEL1="\$i"
		SEL2="\$(echo "\$i" | sed -e "s|\.ext\.gpg$||g" -e "s|\.ext\.pgp$||g" -e "s|\.ext\.gnupg$||g" -e "s|\.ext\.sig$||g" -e "s|\.ext\.asc$||g" -e "s|\.gpg$||g" -e "s|\.pgp$||g" -e "s|\.gnupg$||g" -e "s|\.sig$||g" -e "s|\.asc$||g")"
		gpg --verify "\$SEL1" "\$SEL2"
		if [ "\$?" -ne 0 ] ; then
			echo " "
			echo -e "\$SEL1"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		else
			echo " "
			echo -e "\$SEL1"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		fi
	elif [ "\$(echo "\$i" | grep -aEi "\.int\.ccr$|\.int\.codecrypt$")" != "" ] ; then
		SEL="\$i"
		ccr -v -C --in "\$SEL"
		if [ "\$?" -ne 0 ] ; then
			ccr -v -C < "\$SEL"
			if [ "\$?" -ne 0 ] ; then
				echo " "
				echo -e "\$SEL"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
				echo " "
			else
				echo " "
				echo -e "\$SEL"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
				echo " "
			fi
		else
			echo " "
			echo -e "\$SEL"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "		
		fi
	elif [ "\$(echo "\$i" | grep -aEi "\.ccr$|\.codecrypt$")" != "" ] ; then
		SEL1="\$i"
		SEL2="\$(echo "\$i" | sed -e "s|\.ext\.ccr$||g" -e "s|\.ext\.codecrypt$||g" -e "s|\.ccr$||g" -e "s|\.codecrypt$||g")"
		ccr -v -a -b "\$SEL1" --in "\$SEL2"
		if [ "\$?" -ne 0 ] ; then
			ccr -v -a -b "\$SEL1" < "\$SEL2"
			if [ "\$?" -ne 0 ] ; then
				echo " "
				echo -e "\$SEL1"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
				echo " "
			else
				echo " "
				echo -e "\$SEL1"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
				echo " "
			fi
		else
			echo " "
			echo -e "\$SEL1"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "		
		fi
	else
		echo " "
		echo -e "\$i"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
		echo " "
	fi
done
fi

echo " " >> /tmp/pica-ie_sum-res

#rm -rf /tmp/pica-ie-sum_0 /tmp/pica-ie-sum_1

SUMTEST=\$(ls "\$ISODIR" | grep -aEi "md5$|b2$|sha1$|sha256$|sha512$|sha3$|whirlpool$|md5sum$|b2sum$|sha1sum$|sha256sum$|sha512sum$|sha3sum$|whirlpoolsum$|md5\.txt$|b2\.txt$|sha1\.txt$|sha256\.txt$|sha512\.txt$|sha3\.txt$|whirlpool\.txt$|md5sum\.txt$|b2sum\.txt$|sha1sum\.txt$|sha256sum\.txt$|sha512sum\.txt$|sha3sum\.txt$|whirlpoolsum\.txt$" | grep -a -c ^)
if [ "\$SUMTEST" -ge 1 ] ; then
	true
else
	echo " "
	echo -e "\e[1;31m"$"ERROR:"" "$"No checksum detected.""\e[0m" | tee -a /tmp/pica-ie_sum-res
	echo " "
	echo $"Close this window or press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to close."
	echo " "
	read KEY
fi

if [ "\$SUMTEST" -ge 1 ] ; then
ls "\$ISODIR" | grep -aEi "md5$|b2$|sha1$|sha256$|sha512$|sha3$|whirlpool$|md5sum$|b2sum$|sha1sum$|sha256sum$|sha512sum$|sha3sum$|whirlpoolsum$|md5\.txt$|b2\.txt$|sha1\.txt$|sha256\.txt$|sha512\.txt$|sha3\.txt$|whirlpool\.txt$|md5sum\.txt$|b2sum\.txt$|sha1sum\.txt$|sha256sum\.txt$|sha512sum\.txt$|sha3sum\.txt$|whirlpoolsum\.txt$" | while read i ; do
	unset CHECKSUM
	for TESTSUM in sha512 sha256 whirlpool sha3 sha1 md5 b2 ; do
		if [ "\$CHECKSUM" = "" ] ; then
			if [ "\$(echo "\$i" | grep -aEi "\$TESTSUM$|\$TESTSUM\.txt$|\${TESTSUM}sum$|\${TESTSUM}sum\.txt$")" != "" ] ; then
				CHECKSUM=\$(echo \${TESTSUM}sum | tr "[A-Z]" "[a-z]" )
			fi
		fi
	done
	if [ "\$CHECKSUM" != "" ] ; then
		echo $"Please wait..."
		echo " "
		if ( [ "\$(echo \$CHECKSUM | grep -aEi 'sha512|sha256|sha1|md5|b2')" != "" ] && ( [ "\$(dpkg -l | awk '{print \$1,\$2,\$3}' | grep -aEi ' coreutils | coreutils:' | awk '{print \$3}' | tr '.|-' '\t' | awk '{print \$1}')" -gt 8 ] || [ "\$(dpkg -l | awk '{print \$1,\$2,\$3}' | grep -aEi ' coreutils | coreutils:' | awk '{print \$3}' | tr '.|-' '\t' | awk '{print \$1\$2}')" -ge 825 ] )) || ( [ "\$(echo \$CHECKSUM | grep -aEi 'sha3')" != "" ] && ( [ "\$(dpkg -l | awk '{print \$1,\$2,\$3}' | grep -aEi ' libdigest-sha3-perl | libdigest-sha3-perl:' | awk '{print \$3}' | tr '.|-' '\t' | awk '{print \$1}')" -gt 1 ] || [ "\$(dpkg -l | awk '{print \$1,\$2,\$3}' | grep -aEi ' libdigest-sha3-perl | libdigest-sha3-perl:' | awk '{print \$3}' | tr '.|-' '\t' | awk '{print \$1\$2}')" -ge 103 ] )) ; then
			# Only coreutils >= 8.25 (Debian 9 "Stretch" and later) and libdigest-sha3-perl >= 1.03 (Debian 10 "Buster" and later) and rhash >= 1.4.3 (Debian 12 "Bookworm" and later) have '--ignore-missing' option.  https://lists.gnu.org/archive/html/coreutils/2016-01/msg00075.html  https://metacpan.org/dist/Digest-SHA3/changes  https://rhash.sourceforge.io/changelog.php
			\$(echo \$CHECKSUM | sed 's|rhash|rhash --percents|g') -c --ignore-missing "\$i"
		else
			\$(echo \$CHECKSUM | sed 's|rhash|rhash --percents|g') -c "\$i"
		fi
		if [ "\$?" -ne 0 ] ; then
			echo " "
			echo -e "\$i"" ""\e[1;31m"$"ERROR""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		else
			echo " "
			echo -e "\$i"" ""\e[1;32m"$"Good""\e[0m" | tee -a /tmp/pica-ie_sum-res
			echo " "
		fi
	else
		echo " "
		echo -e "\e[1;31m"$"ERROR:"" "$"No checksum detected.""\e[0m" | tee -a /tmp/pica-ie_sum-res
		echo " "
		echo $"Close this window or press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to close."
		echo " "
		read KEY
	fi
done
fi

NCP=\$(printf "\$ISONAME" | wc -m)
NC=\$(expr \$NCP + 31)
printf %.s'=' \$(seq \$NC) ; echo
echo " "
echo $"Summary:"
echo " "
cat /tmp/pica-ie_sum-res
rm -f /tmp/pica-ie_sum-res
echo " "
printf %.s'=' \$(seq \$NC) ; echo

echo " "
echo $"Close this window or press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to close."
echo " "
read KEY

EOF

	chmod +x /tmp/${CNAME}_sum
	TT="$TITLE" ; COM="bash /tmp/${CNAME}_sum" ; TERMINAL ; rm -f /tmp/${CNAME}_sum

fi

}

checkh_seliso () {

#if [ "$(disktype $SELISO | grep -aEi 'MBR|GPT')" = "" ] ; then
#if [ "$(wipefs $SELISO | grep -aEi 'DOS|GPT')" = "" ] ; then  # util-linux >= 2.31
if [ "$(head -c 512 $SELISO )" = "" ] ; then
	echo "No hybrid IMG/ISO/RAW file"
	NHOPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"$ISONAME does not seem to be a hybrid IMG/ISO/RAW file. The SD card or USB device will not work if the IMG/ISO/RAW file is not hybrid.\n" $H $W $LH $COLUMN $COLUMN \
	$"It is a hybrid IMG/ISO/RAW file. Continue." " " \
	$"Select another IMG/ISO/RAW file." " " \
	$"Stop now" " " \
	| head -n 1 )

	if [ "$?" -ne 0 ] || [ "$NHOPT" = "" ] ; then
		sel_iso
	fi
	
	case $NHOPT in
	
	$"Stop now" )
		clean
		exit 0
	;;
	$"It is a hybrid IMG/ISO/RAW file. Continue." )
		true
	;;
	$"Select another IMG/ISO/RAW file." )
		sel_iso
	;;
	* )
		REFUN=sel_iso
		input_error ; return
	;;
	esac
	
else
	echo "Hybrid IMG/ISO/RAW file"
	true
fi

}

sel_iso () {

#SELISO=$($DIALOG $WICON $WTITLE $"Select the IMG/ISO/RAW file $ISO2PTEXT" $FSEL /home/ $H $W)
SELISO=$($DIALOG $WICON $WTITLE $"Select the IMG/ISO/RAW file" $FSEL /home/ $H $W)

	if [ "$?" -ne 0 ] ; then
		clean
		exit 0
	fi

	if [ "$SELISO" = "" ] ; then
		REFUN=sel_iso
		input_error ; return
	fi

	if [ ! -f "$SELISO" ] ; then
		REFUN=sel_iso
		input_error ; return
	fi

ISONAME=$(echo "$SELISO" | awk -F '/' '{print $NF}')
ISODIR=$(echo "$SELISO" | sed "s|/$ISONAME$||g")

# Decompressing
CHECK_COMP=$(echo "$SELISO" | grep -aEi "\.7z$|\.arj$|\.bkz$|\.bz$|\.bz2$|\.cab$|\.gz$|\.lrz$|\.lz$|\.lz4$|\.lzh$|\.lzma$|\.lzop$|\.nco$|\.rar$|\.xz$|\.z$|\.zab$|\.zip$|\.zipx$|\.zst$|\.zstd$")
CHECK_COMP_ZSTD=$(echo "$SELISO" | grep -aEi "\.zst$|\.zstd$")

if [ "$CHECK_COMP" != "" ] ; then
	
	if [ "$DCTMP" = "" ] ; then
		DCTMP="$ISODIR"
	fi
	cd $DCTMP
	if [ "$CHECK_COMP_ZSTD" != "" ] ; then
		if   [ "$(command -v zstd)" != "" ] ; then
			TT=$"Decompressing... Please wait..." ; COM="zstd -d $SELISO" ; TERMINAL # "zstd -d --output-dir-mirror $DCTMP $SELISO"
		else
			$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"'zstd' must be installed if you want $TITLE to work with 'zstd' compressed files.\n\nCannot continue." $H $W
			exit 1
		fi
	else
		if   [ "$(command -v unar)" != "" ] ; then
			TT=$"Decompressing... Please wait..." ; COM="unar -D $SELISO" ; TERMINAL # "unar -D -o $DCTMP $SELISO"
		elif [ "$(command -v 7z)" != "" ] ; then
			TT=$"Decompressing... Please wait..." ; COM="7z e $SELISO" ; TERMINAL # "7z e -o$DCTMP $SELISO"
		elif [ "$(command -v 7zz)" != "" ] ; then
			TT=$"Decompressing... Please wait..." ; COM="7zz e $SELISO" ; TERMINAL # "7zz e -o$DCTMP $SELISO"
		else
			$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"'unar' or 'p7zip-full' or '7zip' must be installed if you want $TITLE to work with compressed files.\n\nCannot continue." $H $W
			exit 1
		fi
	fi
	
	ISO_DCTMP_1=$(ls "$DCTMP" | grep -aEi "\.img$|\.iso$|\.raw$")
	ISO_DCTMP_2=$(find "$DCTMP" -type f | grep -aEi "\.img$|\.iso$|\.raw$")
	if [ "$ISO_DCTMP_1" != "" ] && [ "$(echo $ISO_DCTMP_1 | grep -a -c ^)" -eq 1 ] ; then
		ISONAME="$ISO_DCTMP_1"
		ISODIR="$DCTMP"
		SELISO="$ISODIR/$ISONAME"
	elif [ "$ISO_DCTMP_2" != "" ] && [ "$(echo $ISO_DCTMP_2 | grep -a -c ^)" -eq 1 ] ; then
		SELISO="$ISO_DCTMP_2"
		ISONAME=$(echo "$SELISO" | awk -F '/' '{print $NF}')
		ISODIR=$(echo "$SELISO" | sed "s|/$ISONAME$||g")
	else
		$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"Decompressed in $DCTMP but $TITLE has not been able to determine which file to use." $H $W
#		clean
		exit 1
	fi
	
fi

echo "SELISO=$SELISO"
echo "ISONAME=$ISONAME"
echo "ISODIR=$ISODIR"

# Check file type
CHECK_SELISO=$(echo "$SELISO" | grep -aEi "\.img$|\.iso$|\.raw$")
if [ "$CHECK_SELISO" = "" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Are you sure $ISONAME is a disk image file?" $H $W
	if [ "$?" -ne 0 ] ; then
		sel_iso ; return 1
	fi
fi

# Check checksum
checksum_seliso

# Check if it is hybrid
checkh_seliso

# Size
ISOSIZEB=$(du -B1 "$SELISO" | awk '{print $1}')
ISOSIZEM=$(expr $ISOSIZEB / 1024 / 1024 )
ISOSIZEG=$(echo "scale=1 ; $ISOSIZEM / 1024" | bc -l )
ISOSIZE=$(du -sh "$SELISO" | awk '{print $1}')

}

sel_iso

#if [ "$ISO2P" = "Y" ] ; then
#	PRESELISO="$SELISO"
#	PREISONAME="$ISONAME"
#	PREISODIR="$ISODIR"
#	ISO2PTEXT=$"(select the second part second)"
#	sel_iso
#	
#	$DIALOG $WICON $WTITLE $"Combining parts..." $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
#	PIDDIALOGIE=$( echo $! )
#	cat "$PRESELISO" "$SELISO" > "$ISODIR/ie-$ISONAME"
#	SELISO="$ISODIR/ie-$ISONAME"
#	kill $PIDDIALOGIE 2>/dev/null
#fi

#fi


### LIVE ########################################

elif [ "$(echo $OPT | grep -a 'L' )" != "" ] ; then
	
	echo "### lsblk ##########"
	lsblk -o NAME,KNAME,RM,SIZE,RO,TYPE,FSTYPE,MOUNTPOINT,LABEL,UUID
	
	if [ "$(cat /proc/cmdline | grep -aEi "boot=live| live-config | live-config$| live | live$|=live |=live$")" = "" ] && [ "$(ls /lib/live/mount/*)" = "" ] && [ "$(ls /usr/lib/live/mount/*)" = "" ] && [ "$(ls /run/live/*)" = "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Are you sure this is a live session (the system is operating from a removable device and not from a system installed on the internal disk)?" $H $W
		if [ "$?" -ne 0 ] ; then
			exit 1
		fi
	fi
	
	SELISO=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE,FSTYPE,MOUNTPOINT | grep -aEi ' iso9660' | grep -aEi live | awk '{print "/dev/"$1}' | head -n 1 )
	if [ "$SELISO" = "" ] ; then
		SELISO="/dev/sr0"
	fi
	
	if [ ! -e "$SELISO" ] ; then
		check_exit
	fi
	echo "SELISO=$SELISO"
	
	# Size
	ISOSIZEB=$(lsblk -r -n -b -o SIZE "$SELISO" | head -n 1 )
	ISOSIZEM=$(expr $ISOSIZEB / 1024 / 1024 )
	ISOSIZE=$(lsblk -r -n -o SIZE "$SELISO" | head -n 1)
	

### CHECK IMG/ISO/RAW ########################################

else

	check_exit

fi


if [ ! -e "$SELISO" ] ; then
	check_exit
fi


### SEL DEV ########################################

echo "### lsblk ##########"
lsblk -o NAME,KNAME,RM,SIZE,RO,TYPE,FSTYPE,MOUNTPOINT,LABEL,UUID
echo "### blkid ##########"
blkid
echo "### by-id ##########"
ls -l /dev/disk/by-id/
echo "#############"


sel_dopt () {

DOPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"The SD card or USB device must be physically plugged to the computer but NOT be mounted (you can do it now before continuing, if it is plugged and mounted $TITLE will try to unmount it).\n\nThe size of the SD card or USB device must be equal to or greater than $ISOSIZE (the size of the IMG/ISO/RAW file).\n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)\n" $H $W $LH $COLUMN $COLUMN \
$"Continue" " " \
$"Open the partition manager" " " \
$"Stop now" " " \
| head -n 1 )

if [ "$?" -ne 0 ] || [ "$DOPT" = "" ] ; then
	clean
	exit 0
fi

case $DOPT in

	$"Stop now" )
		clean
		exit 0
	;;

	$"Continue" )
		true
	;;

	$"Open the partition manager" )
		if [ "$G" = "N" ] ; then
			exec >/dev/tty
			if [ "$(command -v parted)" != "" ] ; then
				parted
			elif [ "$(command -v cfdisk)" != "" ] ; then
				cfdisk
			else
				REFUN=sel_dopt
				input_error ; return
			fi
			if [ "$DEBUG" != "N" ] ; then
				exec > >(tee -a "$ERRORLOG") 2>&1
			fi
		else
			if [ "$(command -v gparted)" != "" ] ; then
				su-to-root -X -c gparted
			elif [ "$(command -v partitionmanager)" != "" ] ; then
				su-to-root -X -c partitionmanager
			elif [ -e /usr/share/applications/gparted.desktop ] ; then
				$(cat /usr/share/applications/gparted.desktop | grep -aE ^Exec= | sed "s|^Exec=||g")
			elif [ -e /usr/share/applications/partitionmanager.desktop ] ; then
				$(cat /usr/share/applications/partitionmanager.desktop | grep -aE ^Exec= | sed "s|^Exec=||g")
			elif [ -e /usr/share/applications/org.kde.partitionmanager.desktop ] ; then
				$(cat /usr/share/applications/org.kde.partitionmanager.desktop | grep -aE ^Exec= | sed "s|^Exec=||g")
			else
				REFUN=sel_dopt
				input_error ; return
			fi
		fi
	;;

esac

}

sel_dopt


check_space () {

	DEVSIZEB=$(lsblk -r -n -b -o SIZE $DEV | head -n 1 )
	DEVSIZEM=$(expr $DEVSIZEB / 1024 / 1024 )
	DEVSIZEG=$(echo "scale=1 ; $DEVSIZEM / 1024" | bc -l )
	DEVSIZE=$(lsblk -r -n -o SIZE $DEV | head -n 1 )

	if [ "$ISOSIZEB" -gt "$DEVSIZEB" ] ; then

		LACKSPACE=$"The size of the IMG/ISO/RAW file ($ISOSIZEM MiB = $ISOSIZEG GiB) is greater than the size of the SD card or USB device ($DEVSIZEM MiB = $DEVSIZEG GiB).\n\nDo you want to select another SD card or USB device?"
	
		$DIALOG $WICON $WTITLE $"SD card or USB device is too small" $WYN   $WTEXT "$LACKSPACE" $H $W
		
			if [ "$?" -eq 0 ] ; then
				selector
			else
				clean
				exit 1
			fi
	fi

}


check_mounted () {

	if [ "$(command -v pumount)" != "" ] ; then
		lsblk -r -n -o KNAME $DEV | while read i ; do pumount /dev/$i ; done
	fi

	lsblk -r -n -o KNAME $DEV | while read i ; do umount /dev/$i ; done

	MOUNTEST=$(lsblk -r -n -o MOUNTPOINT "$DEV" | grep -aE "[a-zA-Z0-9/]" | head -n 1 )
#	MOUNTEST1=$(cat /etc/mtab | grep -aE "^$DEV" | awk '{print $1}')
#	#MOUNTEST1=$(cat /proc/mounts | grep -aE "^$DEV" | awk '{print $1}')
#
#	for i in $(lsblk -r -n -o UUID $DEV | grep -aE "[a-zA-Z0-9]") ; do
#		MOUNTEST2=$(cat /etc/mtab | grep -a "$i " | awk '{print $1}')
#		if [ "$MOUNTEST2" != "" ] ; then break ; fi
#	done
#
#	for i in $(for j in $(lsblk -r -n -o KNAME $DEV) ; do find -L /dev/disk/ -samefile /dev/$j ; done) ; do
#		MOUNTEST3=$(cat /etc/mtab | grep -aE "^$i " | awk '{print $1}')
#		if [ "$MOUNTEST3" != "" ] ; then break ; fi
#	done
#
#	if [ "$MOUNTEST1" != "" ] || [ "$MOUNTEST2" != "" ] || [ "$MOUNTEST3" != "" ] ; then
	if [ "$MOUNTEST" != "" ] ; then
	
		$DIALOG $WICON $WTITLE $"Device is mounted" $WYN   $WTEXT $"Device $DEV is mounted.\n\nDo you want to select another SD card or USB device?" $H $W
	
		if [ "$?" -eq 0 ] ; then
			selector
		else
			clean
			exit 1
		fi
		
	fi

}


check_fstab () {

	FSTABTEST1=$(cat /etc/fstab | grep -aEiv "^#" | grep -aE "^$DEV" | awk '{print $1}')

	for i in $(lsblk -r -n -o UUID $DEV | grep -aE "[a-zA-Z0-9]") ; do
		FSTABTEST2=$(cat /etc/fstab | grep -aEiv "^#" | grep -a "$i " | awk '{print $1}')
		if [ "$FSTABTEST2" != "" ] ; then break ; fi
	done

	for i in $(for j in $(lsblk -r -n -o KNAME $DEV) ; do find -L /dev/disk/ -samefile /dev/$j ; done) ; do
		FSTABTEST3=$(cat /etc/fstab | grep -aEiv "^#" | grep -aE "^$i " | awk '{print $1}')
		if [ "$FSTABTEST3" != "" ] ; then break ; fi
	done

	if [ "$FSTABTEST1" != "" ] || [ "$FSTABTEST2" != "" ] || [ "$FSTABTEST3" != "" ] ; then
	
		$DIALOG $WICON $WTITLE $"$DEV in /etc/fstab" $WYN   $WTEXT $"$DEV seems to be configured in /etc/fstab.\n\nDo you want to select another SD card or USB device?" $H $W
	
		if [ "$?" -eq 0 ] ; then
			selector
		else
			clean
			exit 1
		fi
		
	fi

}


# It should be allowed to use Pica-IE to copy a disk image to an empty internal disk using a live system.
# +
# Some removable devices are incorrectly identified as non-removable.
selectorall () {

DEVLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE | grep -aEi ' disk' | awk '{print $1"\t"$3}' | sort -u )
DEVLISTEXTRAINFO=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE | grep -aEi ' disk' | while read i ; do KNINFO=$(echo "$i" | awk '{print $1}' | sed "s|sd.*|&\t|g"); RM=$(echo "$i" | awk '{print $2}') ; if [ "$RM" -eq 0 ] ; then RMINFO="I" ; elif [ "$RM" -eq 1 ] ; then RMINFO="E" ; else RMINFO=" " ; fi ; SINFO=$(echo "$i" | awk '{print $3}'); DT=$(cat /var/log/syslog | grep -a $KNINFO | tail -n 1 ) ; if [ "$DT" != "" ] ; then TINFO=$(echo $DT | awk '{if ($1 ~ /^20/) print $1 ; else print $3,"h" }') ; fi ; printf "$KNINFO\t$RMINFO\t$SINFO\t$TINFO\n" ; done)

if [ "$(echo "$DEVLISTEXTRAINFO" | grep -a -c ^)" -gt 10 ] ; then
	DEVLISTEXTRAINFO=""
fi

if [ "$DEVLISTSIZE" = "" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"No device detected.\n\nCannot continue." $H $W
	check_exit
fi

unset PREDEV DEV

PREDEV=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"An SD card or USB device with a minimum size of $ISOSIZE is required.\n\nDetected devices:\n\n$DEVLISTEXTRAINFO \n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)\n\nPlease select the device to be used:" $H $W $LH $COLUMN $COLUMN $DEVLISTSIZE | head -n 1 )

	if [ "$?" -ne 0 ] || [ "$PREDEV" = "" ] ; then
		clean
		exit 0
	fi

}


selector () {

DEVLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE | grep -aEi " 1 |^mmc" | grep -aEi ' disk' | awk '{print $1"\t"$3}' | sort -u )
DEVLISTEXTRAINFO=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE | grep -aEi " 1 |^mmc" | grep -aEi ' disk' | while read i ; do KNINFO=$(echo "$i" | awk '{print $1}' | sed "s|sd.*|&\t|g"); RM=$(echo "$i" | awk '{print $2}') ; if [ "$RM" -eq 0 ] ; then RMINFO="I" ; elif [ "$RM" -eq 1 ] ; then RMINFO="E" ; else RMINFO=" " ; fi ; SINFO=$(echo "$i" | awk '{print $3}'); DT=$(cat /var/log/syslog | grep -a $KNINFO | tail -n 1 ) ; if [ "$DT" != "" ] ; then TINFO=$(echo $DT | awk '{if ($1 ~ /^20/) print $1 ; else print $3,"h" }') ; fi ; printf "$KNINFO\t$RMINFO\t$SINFO\t$TINFO\n" ; done)

if [ "$(echo "$DEVLISTEXTRAINFO" | grep -a -c ^)" -gt 10 ] ; then
	DEVLISTEXTRAINFO=""
fi

#if [ "$DEVLISTSIZE" = "" ] ; then
#	REFUN=selector
#	input_error ; return
#fi

ALLDEVS=$"List all devices (only for experts)"

unset PREDEV DEV

PREDEV=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"An SD card or USB device with a minimum size of $ISOSIZE is required.\n\nDetected SD cards and USB devices:\n\n$DEVLISTEXTRAINFO \n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)\n\nPlease select the device to be used:" $H $W $LH $COLUMN $COLUMN $DEVLISTSIZE "$ALLDEVS" " " | head -n 1 )

	if [ "$?" -ne 0 ] || [ "$PREDEV" = "" ] ; then
		clean
		exit 0
	fi

	if [ "$PREDEV" = "$ALLDEVS" ] ; then
		selectorall
	fi

if [ ! -e "/dev/$PREDEV" ] ; then
	REFUN=selector
	input_error ; return
fi

DEV=$(echo "/dev/$PREDEV")
DEVID=$(find -L /dev/disk/by-id/ -samefile $DEV | sort | tail -n 1 )

check_space
check_mounted
check_fstab

echo "DEV=$DEV"
echo "DEVID=$DEVID"

}

selector


#if [ ! -e "$DEV" ] ; then
if [ ! -e "$DEV" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"The device $DEV ($DEVID) does not exist." $H $W
	check_exit
fi


### COPY ########################################

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"The installation to $DEV ($DEVSIZE) ($DEVID) will start if you continue. All existing content in this device will be ERASED.\n\nDo you want to continue?\nPlease cancel if you don't want to do it! \n" $H $W

if [ "$?" -ne 0 ] ; then
	clean
	exit 0
fi

	$DIALOG $WICON $WTITLE "$TITLE" $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
	PIDDIALOGZ=$( echo $! )
for n in {1..9} ; do wipefs -f -a $DEV ; done
dd if=/dev/zero of=$DEV oflag=sync bs=1M count=10
sync
	kill $PIDDIALOGZ 2>/dev/null

### script dd
DD_SCRIPT="$CNAME"_dd_"$(date +%Y%m%d_%H%M%S)"

# ddrescue
# 2008-02-24  1.8  new option: --synchronous = -D
# 2015-09-10  1.20 --synchronous = -y and now -D = --odirect
if [ "$(command -v ddrescue)" != "" ] ; then
cat > /tmp/${DD_SCRIPT} <<EOF
#!/bin/bash

CNAME=$CNAME
VERSION=$VERSION
TITLE=$TITLE

# Translations
if [ "\$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=$TEXTDOMAIN
TEXTDOMAINDIR=$TEXTDOMAINDIR

ERRORLOG="$ERRORLOG"
if [ "$DEBUG" = "Y" ] ; then
	set -xv
fi
if [ "$DEBUG" != "N" ] ; then
exec > >(tee -a "\$ERRORLOG") 2>&1
echo "\$0" "\$*" >> "\$ERRORLOG"
fi

################################

echo $"Please wait..."

# DD COPY
ddrescue --synchronous -e 0 -f -vv "$SELISO" "$DEV"

if [ "\$?" -ne 0 ] ; then
	sync
	printf "\n\n\n"
	echo $"ERROR: The copy failed! "
	touch /tmp/dd_ie_ERROR
	sleep 5
	exit 1
else
	sync
fi
#echo " "
#echo $"Close this window or press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to close."
#echo " "
#read KEY

EOF

elif [ "$(dpkg -l | awk '{print $1,$2,$3}' | grep -aEi ' coreutils | coreutils:' | awk '{print $3}' | tr '.|-' '\t' | awk '{print $1}')" -gt 8 ] || [ "$(dpkg -l | awk '{print $1,$2,$3}' | grep -aEi ' coreutils | coreutils:' | awk '{print $3}' | tr '.|-' '\t' | awk '{print $1$2}')" -ge 824 ] ; then
# dd   https://lists.gnu.org/archive/html/coreutils/2015-07/msg00032.html
cat > /tmp/${DD_SCRIPT} <<EOF
#!/bin/bash

CNAME=$CNAME
VERSION=$VERSION
TITLE=$TITLE

# Translations
if [ "\$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=$TEXTDOMAIN
TEXTDOMAINDIR=$TEXTDOMAINDIR

ERRORLOG="$ERRORLOG"
if [ "$DEBUG" = "Y" ] ; then
	set -xv
fi
if [ "$DEBUG" != "N" ] ; then
exec > >(tee -a "\$ERRORLOG") 2>&1
echo "\$0" "\$*" >> "\$ERRORLOG"
fi

################################

echo $"Please wait..."

# DD COPY
dd if="$SELISO" of="$DEV" oflag=sync bs=1M status=progress

if [ "\$?" -ne 0 ] ; then
	sync
	printf "\n\n\n"
	echo $"ERROR: The copy failed! "
	touch /tmp/dd_ie_ERROR
	sleep 5
	exit 1
else
	sync
fi
#echo " "
#echo $"Close this window or press the 'Enter/Return' key (usually the largest key on the keyboard after the 'space' key) to close."
#echo " "
#read KEY

EOF

else

check_exit

fi

chmod +x /tmp/${DD_SCRIPT}

echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy starts"

#TT=$"Copying the IMG/ISO/RAW file to the SD card or USB device... Please wait..." ; COM="ddrescue --synchronous -e 0 -f -vv "$SELISO" $DEV" ; TERMINAL

TT=$"Copying the IMG/ISO/RAW file to the SD card or USB device... Please wait..." ; COM="bash /tmp/${DD_SCRIPT}" ; TERMINAL

if [ -e "/tmp/dd_ie_ERROR" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"ERROR: The copy failed! \n" $H $W
	cat /tmp/${DD_SCRIPT}
	rm -rf /tmp/dd_ie_ERROR
	check_exit
fi

echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy finished"
rm -f /tmp/${DD_SCRIPT}


### MOD PARTS ########################################

#ISOTEST=$(disktype $SELISO | grep -aEi 'iso9660|iso 9660|iso-9660')
#ISOTEST=$(wipefs $SELISO | grep -aEi 'iso9660|iso 9660|iso-9660')
#ISOTEST=$(head -c 1M $SELISO | grep -aEi 'iso9660|iso 9660|iso-9660')
ISOTEST=$(head -c 1M $SELISO | grep -aEio 'iso9660|iso 9660|iso-9660')
if [ "$ISOTEST" != "" ] ; then
	PARTMAN="sfdisk"
else
	PARTMAN="parted"
fi

echo ISOTEST = $ISOTEST
echo PARTMAN = $PARTMAN

if [ "$PARTMAN" = "sfdisk" ] ; then
	sfdisk -l $DEV
	sfdisk -F $DEV
elif [ "$PARTMAN" = "parted" ] ; then
	parted -s $DEV print
	parted -s $DEV print free
else
	echo ERROR PARTMAN = $PARTMAN
fi

freesize () {
	
	if [ "$(command -v $PARTMAN)" = "" ] ; then
		FREESIZE=0
	elif [ "$PARTMAN" = "sfdisk" ] ; then
		if [ "$(sfdisk -F $DEV | grep -aEi ' 0 ')" = "" ] ; then
			FREESIZE=$(sfdisk -F $DEV | grep -aEi $DEV | sed "s|.*: ||g" | sed "s|, .*||g")
		else
			FREESIZE=0
		fi
	elif [ "$PARTMAN" = "parted" ] ; then
		if [ "$(LANG=C parted -s $DEV unit GB print free | grep -aEi 'Free Space' | tail -n 1 | awk '{print " "$3}' | grep -aEi ' 0.00GB| 0,00GB')" = "" ] ; then
			FREESIZE=$(LANG=C parted -s $DEV print free | grep -aEi 'Free Space' | tail -n 1 | awk '{print $3}')
		else
			FREESIZE=0
		fi
	else
		echo ERROR PARTMAN = $PARTMAN
		FREESIZE=0
	fi
	
}

selsize () {
	
	FREESIZEVAL=$(echo $FREESIZE | sed "s|[a-zA-Z ]||g" | sed "s|,.*||g" | sed "s|\..*||g")
	FREESIZEUNIT=$(echo $FREESIZE | sed "s|[0-9., ]||g" | grep -aEi "^B$|^KB$|^KiB$|^MB$|^MiB$|^GB$|^GiB$|^TB$|^TiB$")
	
	VAR=$($DIALOG $WICON $WTITLE "$TITLE" $FORM  $WTEXT $"There is $FREESIZE of unused space on $DEV ($DEVSIZE) ($DEVID).\n\nPlease write a size as an integer (default unit is $FREESIZEUNIT)$LIMITSIZE:" $H $W $LH     $FORMT $"Size:" $PRELAB1 "$FREESIZEVAL" $POSTLAB1      $FORMT $"Unit:" $PRELAB2 "$FREESIZEUNIT" $POSTLAB2     | sed 's:|:\n:g' )
	
	if [ "$?" -ne 0 ] ; then
		if [ "$ISOTEST" != "" ] ; then
			modiso
		else
			modimg
		fi
		return 1
	fi
	
	N=0 ; while read i ; do N=$(expr $N + 1) ; declare VAR$N="$i" ; echo VAR$N = $(echo \"$(eval echo \$VAR$N)\") ; done  <<< "$VAR"
	#N=0 ; while read i ; do N=$(expr $N + 1) ; declare VAR$N="$i" ; echo VAR$N = $(echo \"$(eval echo \$VAR$N)\") ; done  < <(echo "$VAR")
	#N=0 ; echo "$VAR" | while read i ; do N=$(expr $N + 1) ; declare VAR$N="$i" ; echo VAR$N = $(echo \"$(eval echo \$VAR$N)\") ; done
	
	VAL=$VAR1
	UNIT=$VAR2
	
	echo VAL=$VAL
	echo UNIT=$UNIT
	
	CHECK_VAL=$(echo "$VAL" | sed 's| ||g')
	
	if [ "$CHECK_VAL" = "" ] ; then
		REFUN=selsize
		input_error ; return
	fi
	
	CHECK_VAL=$(echo "$VAL" | sed "s|[0-9]||g")
	
	if [ "$CHECK_VAL" != "" ] ; then
		REFUN=selsize
		input_error ; return
	fi
	
	CHECK_UNIT=$(echo "$UNIT" | sed 's| ||g')
	
	if [ "$CHECK_UNIT" = "" ] ; then
		UNIT=$FREESIZEUNIT
	fi
	
	# printf "^B$|" ; for i in $(echo "KiB, MiB, GiB, TiB" | sed 's|,||g' | sed 's| and | |g') ; do printf "^$(echo $i | grep -aEio ^.)$|^$(echo $i | sed 's|i||g')$|^$i$|" ; done ; echo
	# printf "^B$|" ; for i in $(echo "KiB, MiB, GiB, TiB" | sed 's|,||g' | sed 's| and | |g') ; do printf "^$(echo $i | sed 's|i||g')$|^$i$|" ; done ; echo
	CHECK_UNIT=$(echo "$UNIT" | grep -aEiv "^B$|^KB$|^KiB$|^MB$|^MiB$|^GB$|^GiB$|^TB$|^TiB$")
	
	if [ "$CHECK_UNIT" != "" ] ; then
		REFUN=selsize
		input_error ; return
	fi
	
	if [ "$ENDPARTB" != "" ] ; then
		ENDPARTKB=$(echo "c=( $ENDPARTB / 1000 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTMB=$(echo "c=( $ENDPARTB / 1000 / 1000 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTGB=$(echo "c=( $ENDPARTB / 1000 / 1000 / 1000 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTTB=$(echo "c=( $ENDPARTB / 1000 / 1000 / 1000 / 1000 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTKiB=$(echo "c=( $ENDPARTB / 1024 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTMiB=$(echo "c=( $ENDPARTB / 1024 / 1024 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTGiB=$(echo "c=( $ENDPARTB / 1024 / 1024 / 1024 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		ENDPARTTiB=$(echo "c=( $ENDPARTB / 1024 / 1024 / 1024 / 1024 ) + 0.5 ; scale=0 ; c/1" | bc -l)
		
		if [ "$VAL" -lt "$(eval echo \$ENDPART$UNIT)" ] ; then
			LACKSPACE=$"The selected size ($VAL $UNIT) is smaller than the existing partition ($ENDPARTMB MB = $ENDPARTGB GB)."
			$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT "$LACKSPACE" $H $W
			selsize
			return
		fi
	fi
	
	if [ "$FREESIZEUNIT" = "$UNIT" ] ; then
		if [ "$VAL" -gt "$FREESIZEVAL" ] ; then
			LACKSPACE=$"The selected size ($VAL $UNIT) is larger than the available space ($FREESIZE)."
			$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT "$LACKSPACE" $H $W
			selsize
			return
		fi
	fi
	
}

mountfs () {
	# pmount is only for removable (not internal) devices that mount in /media, and the official stable version does not support btrfs, nilfs2, exfat,...
	if [ "$PARTDEV" = "" ] ; then check_exit ; fi
	if [ "$DTMP" = "" ] ; then DTMP=/tmp/"$CNAME"_"$(date +%Y-%m-%d_%H:%M:%S)" ; fi
	mkdir -pv $DTMP
	mount -o rw $PARTDEV $DTMP ; if [ "$?" -ne 0 ] ; then pmount -w $PARTDEV ; if [ "$?" -ne 0 ] ; then check_exit ; else DTMP=$(lsblk -r -n -o MOUNTPOINT $PARTDEV | grep -aE "[a-zA-Z0-9/]" | head -n 1) ; fi ; fi
	$COM
	unset COM
	umount $PARTDEV ; if [ "$?" -ne 0 ] ; then pumount $PARTDEV ; fi
	umount $DTMP ; if [ "$?" -ne 0 ] ; then pumount $DTMP ; fi
	rmdir $DTMP
	unset DTMP
}

resizefs () {
	
	DTMP=/tmp/"$CNAME"_"$(date +%Y-%m-%d_%H:%M:%S)"
	
	PARTFS=$(lsblk -r -n -o FSTYPE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print $1}')
	PARTDEV=$(lsblk -r -n -o FSTYPE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print "/dev/"$NF}')
	PARTSIZEB=$(lsblk -r -n -b -o SIZE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print $1}')
	PARTSIZE=$(expr $PARTSIZEB / 1024 / 1024 / 1000)
	if [ "$PARTFS" = "ext4" ] || [ "$PARTFS" = "ext3" ] || [ "$PARTFS" = "ext2" ] ; then
		resize2fs $PARTDEV # device unmounted
			if [ "$PARTSIZE" -ge 10 ] ; then
			tune2fs -r 76800 "$PARTDEV"
			else
			tune2fs -m 3 "$PARTDEV"
			fi
	elif [ "$PARTFS" = "btrfs" ] ; then
		COM="btrfs filesystem resize max $DTMP" # path mounted
		mountfs
	elif [ "$PARTFS" = "nilfs2" ] ; then
		COM="nilfs-resize -y $PARTDEV" # device mounted
		mountfs
	elif [ "$PARTFS" = "reiserfs" ] ; then
		resize_reiserfs $PARTDEV # device unmounted
	elif [ "$PARTFS" = "xfs" ] ; then
		COM="xfs_growfs $PARTDEV" # path|device mounted
		mountfs
	elif [ "$PARTFS" = "ntfs" ] ; then
		ntfsresize $PARTDEV # device unmounted
	elif [ "$PARTFS" = "vfat" ] ; then
		fatresize -s max $PARTDEV # device unmounted
	else
		echo "PARTFS=$PARTFS"
	fi
	
}

partmkfs () {
	
	# nilfs2 limitations:  https://nilfs.sourceforge.io/en/current_status.html  https://docs.kernel.org/filesystems/nilfs2.html#caveats
	
	FSLIST=""
	for i in ext2 ext4 ext3 btrfs nilfs2 ntfs vfat ; do
		if [ "$(command -v mkfs.$i)" != "" ] ; then FSLIST="$FSLIST $i $ESP" ; fi
	done

	FSi=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Please select a file system for the partition.\n\n'vfat' is recommended if you want to work with the same data using different users and/or operating systems, otherwise 'ext2' is recommended (in order to preserve permissions and owners, privative operating systems don't usually support this)." $H $W $LH $COLUMN $COLUMN $FSLIST | head -n 1 )

	if [ "$?" -ne 0 ] ; then
		if [ "$ISOTEST" != "" ] ; then
			modiso
		else
			modimg
		fi
		return 1
	fi

	if [ "$FSi" = "" ] ; then
		REFUN=partmkfs
		input_error ; return
	fi

	if [ "$FSi" = "ext4" ] || [ "$FSi" = "ext3" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Do you want to disable the $FSi 'journal' to extend the life of the SD card or USB device at the expense of losing data if the system is accidentally turned off or disconnected?" $H $W
		
		if [ "$?" -eq 0 ] ; then
			JOURNALOFF="Y"
		fi
	fi
	
	PARTDEV=$(lsblk -r -n -o FSTYPE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print "/dev/"$NF}')
	PARTSIZEB=$(lsblk -r -n -b -o SIZE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print $1}')
	PARTSIZE=$(expr $PARTSIZEB / 1024 / 1024 / 1000)
	
	$DIALOG $WICON $WTITLE "$TITLE" $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
	PIDDIALOGFORMATTING=$( echo $! )
	
	for n in {1..9} ; do wipefs -f -a $PARTDEV ; done
	
	if [ "$FSi" = "vfat" ] ; then
		mkfs.$FSi -F 32 "$PARTDEV"
		if [ "$?" -ne 0 ] ; then
			kill $PIDDIALOGFORMATTING 2>/dev/null
			REFUN=partmkfs
			input_error ; return
		fi
	elif [ "$FSi" = "ntfs" ] ; then
		mkfs.$FSi -Q "$PARTDEV"
		if [ "$?" -ne 0 ] ; then
			kill $PIDDIALOGFORMATTING 2>/dev/null
			REFUN=partmkfs
			input_error ; return
		fi
	else
		mkfs.$FSi "$PARTDEV"
		if [ "$?" -ne 0 ] ; then
			kill $PIDDIALOGFORMATTING 2>/dev/null
			REFUN=partmkfs
			input_error ; return
		fi
	fi

	# reserved blocks
	if [ "$FSi" = "ext4" ] || [ "$FSi" = "ext3" ] || [ "$FSi" = "ext2" ] ; then
		if [ "$PARTSIZE" -ge 10 ] ; then
		tune2fs -r 76800 "$PARTDEV"
		else
		tune2fs -m 3 "$PARTDEV"
		fi
	fi
	
	if [ "$JOURNALOFF" = "Y" ] ; then
		tune2fs -f -O ^has_journal "$PARTDEV"
		#mkfs.$FSi -O ^has_journal "$PARTDEV"
	fi
	
	kill $PIDDIALOGFORMATTING 2>/dev/null

}

persistence () {
	
	CHECKPERSIST=$(lsblk -r -n -o LABEL $DEV | grep -aEi "^persistence$")
	
	if [ "$CHECKPERSIST" = "" ] ; then
	
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Do you want the changes and the files you create or download when working with the SD card or USB device to be saved to the recently created partition?" $H $W

		if [ "$?" -eq 0 ] ; then
			
			PARTFS=$(lsblk -r -n -o FSTYPE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print $1}')
			PARTDEV=$(lsblk -r -n -o FSTYPE,TYPE,KNAME $DEV | grep -aEi ' part' | grep -aEi "$ENDPARTN$" | head -n 1 | awk '{print "/dev/"$NF}')
			
			if [ "$FSi" != "$PARTFS" ] ; then
				check_exit
			fi
			
#			$DIALOG $WICON $WTITLE "$TITLE" $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
#			PIDDIALOGPERSIST=$( echo $! )
			
			if [ "$FSi" = "ext4" ] || [ "$FSi" = "ext3" ] || [ "$FSi" = "ext2" ] ; then
				e2label $PARTDEV "persistence"
			elif [ "$FSi" = "btrfs" ] ; then
				btrfs filesystem label $PARTDEV "persistence"
			elif [ "$FSi" = "nilfs2" ] ; then
				nilfs-tune -L "persistence" $PARTDEV
			elif [ "$FSi" = "swap" ] ; then
				swaplabel -L "persistence" $PARTDEV
			elif [ "$FSi" = "jfs" ] ; then
				jfs_tune -L "persistence" $PARTDEV
			elif [ "$FSi" = "reiserfs" ] ; then
				reiserfstune -l "persistence" $PARTDEV
			elif [ "$FSi" = "xfs" ] ; then
				xfs_admin -L "persistence" $PARTDEV
			elif [ "$FSi" = "exfat" ] ; then
				exfatlabel $PARTDEV "persistence"
			elif [ "$FSi" = "ntfs" ] ; then
				ntfslabel $PARTDEV "persistence"
			elif [ "$FSi" = "vfat" ] ; then
				dosfslabel $PARTDEV "persistence"
			else
				echo "FSi=$FSi"
			fi
			
			COM="eval echo '/ union' > \$DTMP/persistence.conf"
			mountfs
			
#			kill $PIDDIALOGPERSIST 2>/dev/null
			
		fi
		
	fi
	
}

modiso () {
	
	# ISO9660 is read-only, so it doesn't make sense to resize it, only an additional partition for persistence may make sense.
	#$"Extend the partition to all the unused space" " " \
	#$"Extend the partition to some size" " " \
	#echo " - + - - " | sfdisk $DEV
	#echo " - +$VAL$UNIT - - " | sfdisk $DEV -N 1
	
	unset LIMITSIZE ENDPARTB ENDPARTKB ENDPARTMB ENDPARTGB ENDPARTTB ENDPARTKiB ENDPARTMiB ENDPARTGiB ENDPARTTiB
	
	freesize
	
	# 'BIOS-MBR/msdos' has a limit of 4 primary partitions.
	CHECKMBR=$(LANG=C sfdisk -l $DEV | grep -aEi 'Disklabel' | awk '{print $NF}')
	NPARTS=$(sfdisk -l $DEV | grep -aEi "^/" | grep -a -c ^)
	if [ "$CHECKMBR" = "dos" ] && [ "$NPARTS" -ge 4 ] ; then
		FREESIZE=0
	fi
	
	if [ "$FREESIZE" != "0" ] ; then
		
		MODPARTS=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"There is $FREESIZE of unused space on $DEV ($DEVSIZE) ($DEVID).\n\nPlease select an option:" $H $W $LH $COLUMN $COLUMN \
		$"Create an additional partition on all the unused space" " " \
		$"Create an additional partition of some size" " " \
		$"Close" " " \
		| head -n 1 )

		if [ "$?" -ne 0 ] || [ "$MODPARTS" = "" ] ; then
			false
		fi

		case $MODPARTS in

			$"Close" )
				true
			;;

			$"Create an additional partition on all the unused space" )
				echo " - + - - " | sfdisk -a $DEV
#				ENDPARTN=$(sfdisk -l $DEV | grep -aEi "^/" | tail -n 1 | awk '{print $1}' | sed "s|.*[a-zA-Z/:-]||g")
#				ENDPARTN=$(sfdisk -l $DEV | grep -aEi "^/" | sed "s| \* ||g" | awk '{print $3,$1,$7}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}' | sed "s|.*[a-zA-Z/:-]||g")
				ENDPARTN=$(sfdisk -l -o Device,End,Type $DEV | grep -aEi "^/" | awk '{print $2,$1,$3}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}' | sed "s|.*[a-zA-Z/:-]||g")
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
				partmkfs
				persistence
			;;

			$"Create an additional partition of some size" )
				LIMITSIZE=$" (WARNING: the maximum size is $FREESIZE)"
				selsize
				echo " - $VAL$UNIT - - " | sfdisk -a $DEV
#				ENDPARTN=$(sfdisk -l $DEV | grep -aEi "^/" | tail -n 1 | awk '{print $1}' | sed "s|.*[a-zA-Z/:-]||g")
#				ENDPARTN=$(sfdisk -l $DEV | grep -aEi "^/" | sed "s| \* ||g" | awk '{print $3,$1,$7}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}' | sed "s|.*[a-zA-Z/:-]||g")
				ENDPARTN=$(sfdisk -l -o Device,End,Type $DEV | grep -aEi "^/" | awk '{print $2,$1,$3}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}' | sed "s|.*[a-zA-Z/:-]||g")
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
				partmkfs
				persistence
				modiso ; return
			;;

			* )
				REFUN=modiso
				input_error ; return
			;;
			
		esac
	
	fi

}

modimg () {
	
	unset LIMITSIZE ENDPARTB ENDPARTKB ENDPARTMB ENDPARTGB ENDPARTTB ENDPARTKiB ENDPARTMiB ENDPARTGiB ENDPARTTiB
	
	freesize
	
	# 'BIOS-MBR/msdos' has a limit of 4 primary partitions.
	CHECKMBR=$(LANG=C parted -s $DEV print | grep -aEi 'Partition Tab' | awk '{print $NF}')
	NPARTS=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | grep -a -c ^)
	if [ "$CHECKMBR" = "msdos" ] && [ "$NPARTS" -ge 4 ] ; then
		FREESIZE=0
	fi
	
	if [ "$FREESIZE" != "0" ] ; then
		
		MODPARTS=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"There is $FREESIZE of unused space on $DEV ($DEVSIZE) ($DEVID).\n\nPlease select an option:" $H $W $LH $COLUMN $COLUMN \
		$"Extend the partition to all the unused space" " " \
		$"Extend the partition to some size" " " \
		$"Create an additional partition on all the unused space" " " \
		$"Create an additional partition of some size" " " \
		$"Close" " " \
		| head -n 1 )

		if [ "$?" -ne 0 ] || [ "$MODPARTS" = "" ] ; then
			false
		fi

		case $MODPARTS in

			$"Close" )
				true
			;;

			$"Extend the partition to all the unused space" )
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				printf "Y\nI\n" | parted -s -a optimal $DEV resizepart $ENDPARTN 100%
				printf "Fix\n" | parted ---pretend-input-tty -a optimal $DEV print
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
				resizefs
			;;

			$"Extend the partition to some size" )
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				ENDPARTB=$(parted -s $DEV unit B print | grep -aEi "^$ENDPARTN |^ $ENDPARTN " | awk '{print $4}' | sed "s|[a-zA-Z/:-].*||g")
				ENDPARTMB=$(parted -s $DEV unit MB print | grep -aEi "^$ENDPARTN |^ $ENDPARTN " | awk '{print $4}' | sed "s|[a-zA-Z/:-].*||g")
				ENDPARTGB=$(parted -s $DEV unit GB print | grep -aEi "^$ENDPARTN |^ $ENDPARTN " | awk '{print $4}' | sed "s|[a-zA-Z/:-].*||g")
				LIMITSIZE=$" (WARNING: the minimum size is $ENDPARTMB MB = $ENDPARTGB GB and the maximum is $FREESIZE)"
				selsize
				unset LIMITSIZE ENDPARTB ENDPARTKB ENDPARTMB ENDPARTGB ENDPARTTB ENDPARTKiB ENDPARTMiB ENDPARTGiB ENDPARTTiB
				printf "Y\nI\n" | parted -s -a optimal $DEV resizepart $ENDPARTN $VAL$UNIT
				printf "Fix\n" | parted ---pretend-input-tty -a optimal $DEV print
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
				resizefs
				modimg ; return
			;;

			$"Create an additional partition on all the unused space" )
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				ENDPARTFM=$(parted -s $DEV unit MB print | grep -aEi "^$ENDPARTN |^ $ENDPARTN " | awk '{print $3}' | sed "s|[a-zA-Z/:-].*||g")
				printf "Y\nI\n" | parted -s -a optimal $DEV mkpart primary $ENDPARTFM 100% # Assume a simple scenario <=4 p
				printf "Fix\n" | parted ---pretend-input-tty -a optimal $DEV print
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				partmkfs
			;;

			$"Create an additional partition of some size" )
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				ENDPARTFM=$(parted -s $DEV unit MB print | grep -aEi "^$ENDPARTN |^ $ENDPARTN " | awk '{print $3}' | sed "s|[a-zA-Z/:-].*||g")
				LIMITSIZE=$" (WARNING: the maximum size is $FREESIZE)"
				selsize
				unset LIMITSIZE ENDPARTB ENDPARTKB ENDPARTMB ENDPARTGB ENDPARTTB ENDPARTKiB ENDPARTMiB ENDPARTGiB ENDPARTTiB
				printf "Y\nI\n" | parted -s -a optimal $DEV mkpart primary $ENDPARTFM $VAL$UNIT # Assume a simple scenario <=4 p
				printf "Fix\n" | parted ---pretend-input-tty -a optimal $DEV print
				blockdev --rereadpt $DEV
				partprobe $DEV
				REPET=0 ; while [ "$(lsblk -r -n $DEV )" = "" ] && [ "$REPET" -lt 120 ] ; do REPET=$(expr $REPET + 1) ; sleep 1 ; done
#				ENDPARTN=$(parted -s $DEV print | grep -aEi "^[0-9]|^ [0-9]" | tail -n 1 | awk '{print $1}')
				ENDPARTN=$(parted -s $DEV unit B print | grep -aEi "^[0-9]|^ [0-9]" | awk '{print $3,$1,$5}' | grep -aEiv extend | sort -n | tail -n 1 | awk '{print $2}')
				partmkfs
				modimg ; return
			;;

			* )
				REFUN=modimg
				input_error ; return
			;;
			
		esac
	
	fi

}


freesize
	
if [ "$FREESIZE" != "0" ] ; then

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"There is $FREESIZE of unused space on $DEV ($DEVSIZE) ($DEVID).\n\nDo you want to modify it to extend the partition and/or add a new partition for personal files?\n\n(If you just want to do a quick test, select 'No/Cancel'.)" $H $W

	if [ "$?" -eq 0 ] ; then
		if [ "$ISOTEST" != "" ] ; then
			modiso
		else
			modimg
		fi
	fi

fi

if [ "$PARTMAN" = "sfdisk" ] ; then
	sfdisk -l $DEV
	sfdisk -F $DEV
elif [ "$PARTMAN" = "parted" ] ; then
	parted -s $DEV print
	parted -s $DEV print free
else
	echo ERROR PARTMAN = $PARTMAN
fi


### END ########################################

$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"$TITLE finished. Device ready.\n\nThank you very much for using PicaLibre. Visit the website www.picalibre.org for more information.\n" $H $W

echo $(date +%Y-%m-%d_%H:%M:%S) $"End" >> "$ERRORLOG"

clean

#if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
if [ "$(id -u)" -eq 0 ] && [ "$DEBUG" = "Y" ] ; then
	RECERRORLOG="$ERRORLOG"
	for i in $(cat /etc/passwd | awk -F ':' '{print $3,$1}' | sort -n | grep -aEi "00[0-9] " | awk '{print $2}') ; do AUSER=$(users | sed 's| |\n|g' | grep -aE "^$i$" | head -n 1) ; if [ "$AUSER" != "" ] ; then
		HOMEERRORLOG=/home/$i/.${CNAME}.log
		RECERRORLOG="$RECERRORLOG $HOMEERRORLOG "
		cp -v --remove-destination $ERRORLOG $HOMEERRORLOG
		if [ "$(id -nu $i)" != "" ] ; then chown $(id -nu $i):$(id -ng $i) $HOMEERRORLOG ; else chown 1000:1000 $HOMEERRORLOG ; fi
		chmod 600 $HOMEERRORLOG ; if [ "$(stat -c %U $HOMEERRORLOG)" != "$i" ] ; then chmod 666 $HOMEERRORLOG ; fi
		break
	fi ; done
fi

exit 0
