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

# picacop
#
# Make backup copies.
#
# 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, dpkg, findutils, gawk | mawk | original-awk, grep, mount | pmount, rsync, sed, util-linux
# Recommends: lxterminal | sakura | xfce4-terminal, menu, pica-skel, x11-xkb-utils
# Suggests: btrfs-progs, gddrescue, cryptsetup, dmsetup, lvm2, mdadm, gparted | parted | partitionmanager | util-linux (<<2.29.2-3) | fdisk, symlinks, tcplay


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

CNAME="picacop"
VERSION="1.3.1"
TITLE="PicaCop"
ICON="/usr/share/icons/picacop.png"

# Translations
if [ "$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=picacop
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=$"Make backup copies."
LDESCRIP=$"$TITLE is a tool to make sporadic backup copies, typically from the internal disk to an external disk."

# 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


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

check_exit () {

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

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

#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
	exit 1
else
	$REFUN
fi

}


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

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

$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"Welcome to $TITLE.\n\n$TITLE is a tool to make sporadic backup copies, typically from the internal disk to an external disk. (Note: $TITLE is a tool to manually making occasional copies, if you want a constant or automatic replication/synchronization then you need something more complex and adjusted to the circumstances and needs of each case.)\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


### CONNECTED DEV? ########################################

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please, if you want to copy to or from an external disk or removable device, ensure it is connected to the computer (or connect it now, before continuing).\n\nDo you want to continue?\n" $H $W

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


### Activate or inactivate encrypted volumes ########################################

act_crypt () {

CRYPTACTIVEPARTS=$(lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' crypt' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' | grep -aEiv "^$i$" ; done | sort -u )
if [ "$CRYPTACTIVEPARTS" = "" ] ; then
	INACTIVECRYPTPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'crypt' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u )
else
	INACTIVECRYPTPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'crypt' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u | grep -av "$CRYPTACTIVEPARTS")
fi

if [ "$CRYPTACTIVEPARTS" != "" ] ; then
	INFOCRYPTACTIVEPARTS=$(echo $"Partitions that contain active encrypted volumes:" ; lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' crypt' | awk '{print "/dev/"$1}' | sort -u | while read i ; do echo "$i : $(lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' | grep -aEiv "^$i$" | tr "\n" " ")" ; done | sort -u ; echo \\n )
else
	INFOCRYPTACTIVEPARTS=""
fi

if [ "$INACTIVECRYPTPARTS" != "" ] ; then
	INFOINACTIVEQCRYPT=$"The partitions\n$INACTIVECRYPTPARTS\ncontain inactive encrypted volumes.\n\n"
else
	INFOINACTIVEQCRYPT=""
fi

if [ "$CRYPTACTIVEPARTS" != "" ] || [ "$INACTIVECRYPTPARTS" != "" ] ; then

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 "#############"

	if [ "$(command -v cryptsetup)" != "" ] ; then
	QCRYPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"${INFOCRYPTACTIVEPARTS}${INFOINACTIVEQCRYPT}Please select an option:" $H $W $LH $COLUMN $COLUMN $"Activate all identified encrypted volumes" " " $"Inactivate all activated encrypted volumes" " " $"Leave as is" " " | head -n 1 )
	elif [ "$(command -v dmsetup)" != "" ] ; then
	QCRYPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"${INFOCRYPTACTIVEPARTS}${INFOINACTIVEQCRYPT}Please select an option:" $H $W $LH $COLUMN $COLUMN $"Inactivate all activated encrypted volumes" " " $"Leave as is" " " | head -n 1 )
	else
	true
	fi

	case $QCRYPT in
	
		$"Activate all identified encrypted volumes" )

# Open all existing encrypted volumes WITH headers:
#cat << EOF > /tmp/opencrypt
cat > /tmp/opencrypt <<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

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

CRYPTACTIVEPARTS=\$(lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' crypt' | awk '{print "/dev/"\$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s \$i | grep -aEiv ' disk' | awk '{print "/dev/"\$2}' | grep -aEiv "^\$i\$" ; done | sort -u )

if [ "\$CRYPTACTIVEPARTS" = "" ] ; then
	for i in \$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'crypt' | awk '{print "/dev/"\$1}' | sort -u ) ; do lsblk -r -n -o KNAME,SIZE,LABEL,UUID | grep -aE "^\$(echo \$i | sed 's|/dev/||g') " ; cryptsetup luksOpen \$i e\$(echo \$i | sed 's|/dev/||g') ; done
else
	for i in \$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'crypt' | awk '{print "/dev/"\$1}' | sort -u | grep -av "\$CRYPTACTIVEPARTS" ) ; do lsblk -r -n -o KNAME,SIZE,LABEL,UUID | grep -aE "^\$(echo \$i | sed 's|/dev/||g') " ; cryptsetup luksOpen \$i e\$(echo \$i | sed 's|/dev/||g') ; done
fi

EOF

chmod +x /tmp/opencrypt

exec >/dev/tty
TT="$TITLE" ; COM="bash /tmp/opencrypt" ; TERMINAL ; rm -f /tmp/opencrypt
if [ "$DEBUG" != "N" ] ; then
	exec > >(tee -a "$ERRORLOG") 2>&1
fi

		;;
	
		$"Inactivate all activated encrypted volumes" )
		lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' crypt' | awk '{print "/dev/"$1}' | sort -u | while read i ; do
			echo "$i"
			umount $i
			cryptsetup luksClose $i
			tcplay -u $i
			dmsetup remove $i
			## umount /dev/dm*
			#dmsetup remove_all
		done
		;;
	
		*)
		echo "\$?=$?"
		echo QCRYPT=$QCRYPT
		;;

	esac

fi

symlinks -drs /dev/ >>$ERRORLOG
ls -p /dev/ | grep -a / | while read i ; do rmdir -p /dev/$i 2>>$ERRORLOG ; done

}

#act_crypt


### Activate or inactivate LVM ########################################

act_lvm () {

LVMACTIVEPARTS=$(lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' lvm' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' | grep -aEiv "^$i$" ; done | sort -u )
if [ "$LVMACTIVEPARTS" = "" ] ; then
	INACTIVELVMPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'lvm' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u )
else
	INACTIVELVMPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'lvm' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u | grep -av "$LVMACTIVEPARTS")
fi

if [ "$LVMACTIVEPARTS" != "" ] ; then
#	INFOLVMACTIVEPARTS=$(echo $"Active 'LVM' extended volumes:" ; LANG=C pvscan | grep -aEiv 'Total: ' | grep -aEiv "No matching|No device" | awk '{if ( $4 !~ /\[/ ) print $4}' | sort -u | while read i ; do echo "$(echo $(lsblk -r -n -o NAME,KNAME | grep -aEi "^$i-" | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$NF}' | sort -u ))"" '""$i""' "$"formed by the partitions ""$(echo $(pvscan | grep -aE " $i " | awk '{print $2}' | sort -u | grep -av unknown | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]" ))" ; done ; echo \\n )
#	INFOLVMACTIVEPARTS=$(echo $"Active 'LVM' extended volumes:" ; LANG=C pvscan | grep -aEiv 'Total: ' | grep -aEiv "No matching|No device" | awk '{if ( $3 == "VG" ) print $4}' | sort -u | while read i ; do echo "$(echo $(lsblk -r -n -o NAME,KNAME | grep -aEi "^$i-" | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$NF}' | sort -u ))"" '""$i""' "$"formed by the partitions ""$(echo $(pvscan | grep -aE " $i " | awk '{print $2}' | sort -u | grep -av unknown | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]" ))" ; done ; echo \\n )
#	INFOLVMACTIVEPARTS=$(echo $"Active 'LVM' extended volumes:" ; lvs --noheadings --unbuffered -o vg_name,lv_name | sed 's|-|--|g' | sed "s|^ \+||g" | sed "s| \+$||g" | sed 's| |-|g' | sort -u | while read i ; do echo "$(echo $(lsblk -r -n -o NAME,KNAME | grep -aEi "^$i " | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$NF}' | sort -u ))"" '""$i""' "$"formed by the partitions ""$(echo $(pvscan | grep -aE " $(echo $i | grep -aEio ".*[a-zA-Z0-9]-[a-zA-Z0-9]" | sed "s|..$||g" | sed 's|--|-|g') " | awk '{print $2}' | sort -u | grep -av unknown | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]"))" ; done ; echo \\n )
	INFOLVMACTIVEPARTS=$(echo $"Active 'LVM' extended volumes:" ; lsblk -r -n -o NAME,KNAME,RM,TYPE | grep -aEi ' lvm' | awk '{if ( $4 == "lvm" ) print $1}' | grep -aEi "[a-zA-Z0-9]" | sort -u | while read i ; do echo "$(echo $(lsblk -r -n -o NAME,KNAME | grep -aEi "^$i " | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$NF}' | sort -u ))"" '""$i""' "$"formed by the partitions ""$(echo $(pvscan | grep -aE " $(echo $i | grep -aEio ".*[a-zA-Z0-9]-[a-zA-Z0-9]" | sed "s|..$||g" | sed 's|--|-|g') " | awk '{print $2}' | sort -u | grep -av unknown | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]" | grep -aEi "[a-zA-Z0-9]" | while read j ; do lsblk -r -n -o NAME,KNAME,TYPE -s $j | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u))" ; done ; echo \\n )
else
	INFOLVMACTIVEPARTS=""
fi

if [ "$INACTIVELVMPARTS" != "" ] ; then
	INFOINACTIVELVMPARTS=$"The partitions\n$INACTIVELVMPARTS\nare part of inactive 'LVM' extended volumes.\n\n"
else
	INFOINACTIVELVMPARTS=""
fi

if [ "$(command -v vgchange)" != "" ] ; then if [ "$LVMACTIVEPARTS" != "" ] || [ "$INACTIVELVMPARTS" != "" ] ; then

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 "#############"

	QLVM=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"${INFOLVMACTIVEPARTS}${INFOINACTIVELVMPARTS}Please select an option:" $H $W $LH $COLUMN $COLUMN $"Activate all 'LVM' extended volumes" " " $"Inactivate all 'LVM' extended volumes" " " $"Leave as is" " " | head -n 1 )

	case $QLVM in
	
		$"Activate all 'LVM' extended volumes" )
		vgchange -ay
		#pvscan --cache -aay
		;;
	
		$"Inactivate all 'LVM' extended volumes" )
		lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' lvm' | awk '{print "/dev/"$1}' | sort -u | while read i ; do umount $i ; done
		vgchange -an
		;;
	
		*)
		echo "\$?=$?"
		echo QLVM=$QLVM
		;;

	esac

fi ; fi

symlinks -drs /dev/ >>$ERRORLOG
ls -p /dev/ | grep -a / | while read i ; do rmdir -p /dev/$i 2>>$ERRORLOG ; done

}

#act_lvm


### Activate or inactivate RAID ########################################

act_mdadm () {

MDADMACTIVEPARTS=$(lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' raid' | awk '{print "/dev/"$1}' | sort -u | while read i ; do mdadm --detail $i | grep -a " /dev/" | awk '{print $NF}' | sort -u | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]" | while read j ; do lsblk -r -n -o NAME,KNAME,TYPE -s $j | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done ; done | grep -aEi "[a-zA-Z0-9]" | sort -u )
if [ "$MDADMACTIVEPARTS" = "" ] ; then
	INACTIVEMDADMPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'raid' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u )
else
	INACTIVEMDADMPARTS=$(lsblk -r -n -o KNAME,RM,FSTYPE | grep -aEi 'raid' | awk '{print "/dev/"$1}' | sort -u | while read i ; do lsblk -r -n -o NAME,KNAME,TYPE -s $i | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u | grep -av "$MDADMACTIVEPARTS")
fi

if [ "$MDADMACTIVEPARTS" != "" ] ; then
	INFOMDADMACTIVEPARTS=$(echo $"Active 'mdadm' RAID partitions systems:" ; lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' raid' | awk '{print "/dev/"$1}' | sort -u | while read i ; do echo $i $"formed by the partitions" $(mdadm --detail $i | grep -a " /dev/" | awk '{print $NF}' | sort -u | xargs -r0 readlink -m | grep -aEi "[a-zA-Z0-9]" | while read j ; do lsblk -r -n -o NAME,KNAME,TYPE -s $j | grep -aEiv ' disk' | awk '{print "/dev/"$2}' ; done | sort -u) ; done ; echo \\n )
else
	INFOMDADMACTIVEPARTS=""
fi

if [ "$INACTIVEMDADMPARTS" != "" ] ; then
	INFOINACTIVEMDADMPARTS=$"The partitions\n$INACTIVEMDADMPARTS\nare part of inactive RAID partitions systems.\n\n"
else
	INFOINACTIVEMDADMPARTS=""
fi

if [ "$(command -v mdadm)" != "" ] ; then if [ "$MDADMACTIVEPARTS" != "" ] || [ "$INACTIVEMDADMPARTS" != "" ] ; then

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 "#############"

	QMDADM=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"${INFOMDADMACTIVEPARTS}${INFOINACTIVEMDADMPARTS}Please select an option:" $H $W $LH $COLUMN $COLUMN $"Activate all RAID partitions systems" " " $"Inactivate all RAID partitions systems" " " $"Leave as is" " " | head -n 1 )

	case $QMDADM in
	
		$"Activate all RAID partitions systems" )
		mdadm --assemble --scan
		;;
	
		$"Inactivate all RAID partitions systems" )
		lsblk -r -n -o KNAME,RM,TYPE | grep -aEi ' raid' | awk '{print "/dev/"$1}' | sort -u | while read i ; do umount $i ; done
		mdadm --stop --scan
		;;
	
		*)
		echo "\$?=$?"
		echo QMDADM=$QMDADM
		;;

	esac

fi ; fi

symlinks -drs /dev/ >>$ERRORLOG
ls -p /dev/ | grep -a / | while read i ; do rmdir -p /dev/$i 2>>$ERRORLOG ; done

}

#act_mdadm


#if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
if [ "$(id -u)" -eq 0 ] ; then
	act_crypt
	act_lvm
	act_mdadm
fi


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

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 "#############"

check_space () {

	if [ "$OPT" = "$SELDIS" ] ; then
	
		SEL_SIZE_B=$(lsblk -r -n -b -o SIZE "$SEL" | head -n 1 )
		SEL_SIZE_M=$(expr $SEL_SIZE_B / 1024 / 1024 )
	
#	elif [ "$OPT" = "$SELDIR" ] ; then
#	
#		# Slow...
#		SEL_SIZE_B=$(du -s -B1 "$SEL" | awk '{print $1}')
#		SEL_SIZE_M=$(expr $SEL_SIZE_B / 1024 / 1024 )
	
		PREDEST_FREE_B=$(df -B1 "$PREDEST" | grep -aEi "^/" | awk '{print $4}')
		PREDEST_FREE_M=$(expr $PREDEST_FREE_B / 1024 / 1024 )
	
		if [ "$PREDEST_FREE_B" -lt "$SEL_SIZE_B" ] ; then
	
		LACKSPACE=$"The size of $SEL is $SEL_SIZE_M MiB.\n\nIn $PREDEST only $PREDEST_FREE_M MiB is available (unless you erase or move some files).\n\n$TITLE will fail if there is not sufficient free space to write the files.\n\nDo you want to select another destination?"
	
		$DIALOG $WICON $WTITLE $"Insufficient disk space" $WYN   $WTEXT "$LACKSPACE" $H $W
	
			if [ "$?" -eq 0 ] ; then
				dest_dialog ; return
			elif [ "$?" -eq 1 ] ; then
				true
			else
				REFUN=sel_dialog
				input_error ; return
			fi
	
		fi

	else

	#$DIALOG $WICON $WTITLE "$TITLE" $WM    $WTEXT $"Warning: $TITLE will fail if there is not sufficient free space to write the files.\n" $H $W
	$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"Note that $TITLE will fail if there is not sufficient free space to write the files.\n" $H $W

	fi

}


# SELDIS

check_mounted () {

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

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

	MOUNTEST=$(lsblk -r -n -o MOUNTPOINT "$SEL" | grep -aE "[a-zA-Z0-9/]" | head -n 1 )
#	MOUNTEST1=$(cat /etc/mtab | grep -aE "^$SEL" | awk '{print $1}')
#	#MOUNTEST1=$(cat /proc/mounts | grep -aE "^$SEL" | awk '{print $1}')
#
#	for i in $(lsblk -r -n -o UUID $SEL | 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 $SEL) ; 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 $SEL is mounted.\n\nDo you want to select another SD card or USB device?" $H $W
	
		if [ "$?" -eq 0 ] ; then
			seldis
		else
			exit 1
		fi
		
	fi

}


seldis () {

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

OPENPARTEDITOR=$"Open the partition manager"

unset PRESEL SEL

PRESEL=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Detected devices:\n\n$DEVLISTEXTRAINFO \n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)\n\nPlease select the device that you want to copy (if you don't know which one is, use a partition manager as 'gparted' to search it):" $H $W $LH $COLUMN $COLUMN $DEVLISTSIZE "$OPENPARTEDITOR" " " | head -n 1 )

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

	if [ "$PRESEL" = "$OPENPARTEDITOR" ] ; then

		if [ "$G" = "N" ] ; then
			exec >/dev/tty
			if [ "$(command -v parted)" != "" ] ; then
				parted
			elif [ "$(command -v cfdisk)" != "" ] ; then
				cfdisk
			else
				REFUN=seldis
				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=seldis
				input_error ; return
			fi
		fi

		seldis ; return

	fi

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

SEL=$(echo "/dev/$PRESEL")
SELID=$(find -L /dev/disk/by-id/ -samefile $SEL | sort | tail -n 1 )
SEL_MP=""
SEL_DEV="$SEL"

#check_space
check_mounted

}


seldir () {

unset SEL

SEL=$($DIALOG $WICON $WTITLE $"Please select the folder/directory that you want to copy" $DSEL /home/ $H $W)

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

if [ "$SEL" = "" ] ; then
	REFUN=sel_dialog
	input_error ; return
fi

if [ ! -d "$SEL" ] ; then
	REFUN=sel_dialog
	input_error ; return
fi

SELID=""
SEL_MP="$SEL"
SEL_DEV=$(echo "/dev/"$(lsblk -r -n -o KNAME $(df "$SEL" | grep -aEi "^/" | awk '{print $1}')))

}


sel_dialog () {

	SELDIR=$"Copy a folder/directory"

	SELDIS=$"Copy a disk as IMG/RAW file"

	STOPNOW=$"Stop now"

	OPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"You can copy all the content of a folder/directory for example /home/your-username (this is the most usual) or create an IMG/RAW replica file of a disk (in this case the copied content is not directly accessible or usable as the original files are). You probably want the first option.\n\nPlease select an option:" $H $W $LH $COLUMN $COLUMN "$SELDIR" " " "$SELDIS" " " "$STOPNOW" " " | head -n 1 )

	if [ "$?" -ne 0 ] || [ "$OPT" = "" ] ; then
		exit 0
	elif [ "$OPT" = "$STOPNOW" ] ; then
		exit 0
	elif [ "$OPT" = "$SELDIR" ] ; then
		seldir
	elif [ "$OPT" = "$SELDIS" ] ; then
		seldis
	else
		REFUN=sel_dialog
		input_error ; return
	fi

}

sel_dialog

echo "SEL=\"${SEL}\""


dest_dialog () {

unset PREDEST DEST

#PREDEST=$(find /media -maxdepth 2 -type d -name $COPIAS)

	PREDEST=$($DIALOG $WICON $WTITLE $"Please select the folder/directory to dump the backup copy" $DSEL /media/ $H $W)

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

	if [ "$PREDEST" = "" ] ; then
		dest_dialog
	fi
	
	if [ ! -d "$PREDEST" ] ; then
		dest_dialog
	fi


check_space

# Check: The destination folder/directory (the folder/directory to dump the backup copy) cannot be within the backuped folder/directory
if [ "${SEL_MP}" != "" ] ; then
	TEST1=$(echo "$PREDEST" | grep -aE "^${SEL_MP}")
	TEST2=$(echo $(readlink -m "$PREDEST") | grep -aE "^$(readlink -m "$SEL_MP")")
	if [ "$TEST1" != "" ] || [ "$TEST2" != "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"The folder/directory to dump the backup copy cannot be within the backuped folder/directory." $H $W
		dest_dialog
	fi
fi

}

dest_dialog

DEST=$(echo "$PREDEST")
echo "DEST=\"${DEST}\""

DEST_MP="$DEST"
DEST_DEV=$(echo "/dev/"$(lsblk -r -n -o KNAME $(df "$DEST" | grep -aEi "^/" | awk '{print $1}')))


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

DATE=$(date +%Y%m%d_%H%M%S)

if [ "$OPT" = "$SELDIR" ] ; then

RSYNCOPT=$($DIALOG $WICON $WTITLE "$TITLE" $MULTIPLELIST $WTEXT $"Optionally you can change the default settings now.\n" $H $W $LH $COLUMN $COLUMN $COLUMN \
$PRE "L " $"Substitute the copied links for the linked files or folders/directories" $POST \
$PRE "M " $"Create links to previous copy to save disk space" $POST \
$PRE "D " $"Move to COP_$CNAME those files that exist in the destination but not in the backuped folder" $POST \
$PRE "C " $"Compare using checksum instead of modification time and size" $POST \
$PRE "X " $"Stop now" $POST \
| sed 's|(.*)||g' | sed 's| .*||g' | sed 's|^TRUE||g' )

	if [ "$(echo $RSYNCOPT | grep -o X )" != "" ] ; then
		exit 0
	fi

	if [ "$(echo $RSYNCOPT | grep -o M )" != "" ] ; then
		LINKDEST="Y"
	else
		LINKDEST=""
	fi

	if [ "$(echo $RSYNCOPT | grep -o L )" != "" ] ; then
		ROPT="-rLptgoDHAXES"
	else
		ROPT="-aHAXES"
	fi

	if [ "$(echo $RSYNCOPT | grep -o D )" != "" ] ; then
		DOPT="--delete -b --backup-dir=COP_$CNAME"
	else
		DOPT=""
	fi

	if [ "$(echo $RSYNCOPT | grep -o C )" != "" ] ; then
		COPT=" -c"
	else
		COPT=""
	fi

	if [ "$(dpkg -l | awk '{print $1,$2,$3}' | grep -aEi ' rsync | rsync:' | awk '{print $3}' | tr '.|-' '\t' | awk '{print $1}')" -gt 3 ] || [ "$(dpkg -l | awk '{print $1,$2,$3}' | grep -aEi ' rsync | rsync:' | awk '{print $3}' | tr '.|-' '\t' | awk '{print $1$2}')" -ge 31 ] ; then
		PROGRESS="--info=progress2"
	else
		PROGRESS="--progress"
	fi

	FDEST=$(echo "$DEST/$DATE")
	if [ -e "$FDEST" ] ; then
		mv -f "$FDEST" "${FDEST}_COP_$DATE"
	fi

	RSYNC_SCRIPT="$CNAME"_"$DATE"

#cat << EOF > /tmp/${RSYNC_SCRIPT}
cat > /tmp/${RSYNC_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..."

FDEST="$FDEST"
#DATE=\$(date +%Y%m%d_%H%M%S)
#FDEST=\$(echo "$DEST/\$DATE")
#if [ -e "\$FDEST" ] ; then
#	mv -f "\$FDEST" "\${FDEST}_COP_\$DATE"
#fi

TESTLINKDEST=\$(ls "$DEST" | grep -aEi "^2[0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]_[0-2][0-9]:[0-6][0-9]:[0-6][0-9]$" | sort | tail -n 1 )

mkdir -pv "\$FDEST"

if [ "$LINKDEST" = "Y" ] && [ "\$TESTLINKDEST" != "" ] ; then
	rsync $ROPT$COPT $PROGRESS --log-file="$ERRORLOG" --link-dest="$DEST/\$TESTLINKDEST" $DOPT "$SEL"/ "\$FDEST"/
else
	rsync $ROPT$COPT $PROGRESS --log-file="$ERRORLOG" $DOPT "$SEL"/ "\$FDEST"/
fi

find "\$FDEST/COP_$CNAME" -type f | grep -a 'COP_$CNAME/COP_$CNAME' | while read i ; do echo mv "\$i" ; mv "\$i" "\$(echo "\$i" | sed 's|COP_$CNAME/COP_$CNAME|COP_$CNAME|g')" ; done
find "\$FDEST/COP_$CNAME" -type d | sort -r | while read i ; do rmdir "\$i" 1>/dev/null 2>&1 ; done

sync

#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
if [ "\$(id -u)" -eq 0 ] ; then
	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
		chown \$(id -nu \$i):\$(id -ng \$i) "\$FDEST"
		break
	fi ; done
fi

EOF

	chmod +x /tmp/${RSYNC_SCRIPT}

	$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"$TITLE will start the copy from $SEL to $FDEST \n\nThe process may take a while.\n\nDo you want to continue?\n" $H $W

	if [ "$?" -ne 0 ] ; then
		exit 0
	else
	
		echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy starts"
	
		TT=$"Copying files... Please wait..." ; COM="bash /tmp/${RSYNC_SCRIPT}" ; TERMINAL
	
		echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy finished"
	
	fi


elif [ "$OPT" = "$SELDIS" ] ; then

	FDEST=$(echo "$DEST/${PRESEL}_${DATE}.raw")
	if [ -e "$FDEST" ] ; then
		mv -f "$FDEST" "${FDEST}_COP_${DATE}.raw"
	fi

	DD_SCRIPT="$CNAME"_dd_"$DATE"

# 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..."

FDEST="$FDEST"
#DATE=\$(date +%Y%m%d_%H%M%S)
#FDEST=\$(echo "$DEST/${PRESEL}_\${DATE}.raw")
#if [ -e "\$FDEST" ] ; then
#	mv -f "\$FDEST" "\${FDEST}_COP_\${DATE}.raw"
#fi

# DD COPY
ddrescue --synchronous -e 0 -f -vv "$SEL" "\$FDEST"

if [ "\$?" -ne 0 ] ; then
	
	sync
	
	#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
	if [ "\$(id -u)" -eq 0 ] ; then
		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
			chown \$(id -nu \$i):\$(id -ng \$i) "\$FDEST"
			break
		fi ; done
	fi
	
	printf "\n\n\n"
	echo $"ERROR: The copy failed! "
	touch /tmp/dd_cop_ERROR
	sleep 5
	exit 1
	
else
	
	sync
	
	#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
	if [ "\$(id -u)" -eq 0 ] ; then
		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
			chown \$(id -nu \$i):\$(id -ng \$i) "\$FDEST"
			break
		fi ; done
	fi
	
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..."

FDEST="$FDEST"
#DATE=\$(date +%Y%m%d_%H%M%S)
#FDEST=\$(echo "$DEST/${PRESEL}_\${DATE}.raw")
#if [ -e "\$FDEST" ] ; then
#	mv -f "\$FDEST" "\${FDEST}_COP_\${DATE}.raw"
#fi

# DD COPY
dd if="$SEL" of="\$FDEST" oflag=sync bs=1M status=progress

if [ "\$?" -ne 0 ] ; then
	
	sync
	
	#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
	if [ "\$(id -u)" -eq 0 ] ; then
		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
			chown \$(id -nu \$i):\$(id -ng \$i) "\$FDEST"
			break
		fi ; done
	fi
	
	printf "\n\n\n"
	echo $"ERROR: The copy failed! "
	touch /tmp/dd_cop_ERROR
	sleep 5
	exit 1
	
else
	
	sync
	
	#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
	if [ "\$(id -u)" -eq 0 ] ; then
		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
			chown \$(id -nu \$i):\$(id -ng \$i) "\$FDEST"
			break
		fi ; done
	fi
	
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}

	$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"$TITLE will start the copy from $SEL to $FDEST \n\nThe process may take a while.\n\nDo you want to continue?\n" $H $W

	if [ "$?" -ne 0 ] ; then
		exit 0
	else
	
		echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy starts"
	
		TT=$"Copying files... Please wait..." ; COM="bash /tmp/${DD_SCRIPT}" ; TERMINAL
	
		if [ -e "/tmp/dd_cop_ERROR" ] ; then
			$DIALOG $WICON $WTITLE "$TITLE" $ERROR $WTEXT $"ERROR: The copy failed! \n" $H $W
			cat /tmp/${DD_SCRIPT}
			rm -rf /tmp/dd_cop_ERROR
			check_exit
		fi
	
		echo $(date +%Y-%m-%d_%H:%M:%S) $"Copy finished"
	
	fi

else

	check_exit

fi


### CHECKSUM ########################################

unset CHECKSUM

CHECKSUM=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Optionally you can now calculate and compare the checksums of the backuped files.\n\nIt is slow! \n\n'No/Cancel' is recommend, otherwise MD5.\n" $H $W $LH $COLUMN $COLUMN \
 "md5sum"       $"MD5" \
 "b2sum"        $"BLAKE2" \
 "sha1sum"      $"SHA1" \
 "sha256sum"    $"SHA256" \
 "sha512sum"    $"SHA512" \
 | head -n 1 )

if [ "$CHECKSUM" != "" ] ; then

#cat << EOF > /tmp/${CNAME}_${CHECKSUM}
cat > /tmp/${CNAME}_${CHECKSUM} <<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..."

if [ "$OPT" = "$SELDIS" ] ; then
	if [ -e "$CHECKSUM.txt" ] ; then rm -fv $CHECKSUM.txt ; fi
	$CHECKSUM "$SEL" | tee -a $CHECKSUM.txt
	mv -f $CHECKSUM.txt "$DEST"/$CHECKSUM.txt
	cd "$DEST"
	sed -i 's|/dev/||g' $CHECKSUM.txt
	sed -i "s|$PRESEL|${PRESEL}_${DATE}.raw|g" $CHECKSUM.txt
else
	cd "$SEL"
	if [ -e "$CHECKSUM.txt" ] ; then rm -fv $CHECKSUM.txt ; fi
	find {,.[!.],..?}* -type f ! -name $CHECKSUM.txt -print0 2>>"$ERRORLOG" | sort -z | xargs -r0 $CHECKSUM | tee -a $CHECKSUM.txt
	mv -f $CHECKSUM.txt "$FDEST"/$CHECKSUM.txt
	cd "$FDEST"
fi

#if [ "\$(cat /etc/passwd | grep -aE ^\$(whoami): | cut -d ':' -f 3 )" -eq 0 ] ; then
if [ "\$(id -u)" -eq 0 ] ; then
	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
		chown \$(id -nu \$i):\$(id -ng \$i) $CHECKSUM.txt
		break
	fi ; done
fi

echo " "

$CHECKSUM -c $CHECKSUM.txt

if [ "\$?" -ne 0 ] ; then
	set +xv
	printf "\\n\\n\\n"
	echo $"ERROR: The copy failed! "
	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
	exit 1
else
	set +xv
	printf "\\n\\n\\n"
	echo $"All right! "
	echo " "
	sleep 3
	exit 0
fi

EOF
chmod +x /tmp/${CNAME}_${CHECKSUM}

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

TT=$"Checking..." ; COM="bash /tmp/${CNAME}_${CHECKSUM}" ; TERMINAL ; rm -f /tmp/${CNAME}_${CHECKSUM}

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

fi


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

$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"Copy finished.\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"

#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
