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

# picarec
#
# Recover deleted files.
#
# 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, btrfs-progs | ext4magic | extundelete | fatcat | ntfs-3g, coreutils, dialog | yad | yad-pica | zenity, findutils, gawk | mawk | original-awk, grep, lsof, procps, sed, util-linux
# Recommends: lxterminal | sakura | xfce4-terminal, menu, pica-skel, sleuthkit, testdisk, x11-xkb-utils
# Suggests: cryptsetup, dmsetup, lvm2, mdadm, mount, symlinks, tcplay
#
# View https://bugs.debian.org/969495#10 https://bugs.debian.org/1119235


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

CNAME="picarec"
VERSION="1.3.1"
TITLE="PicaRec"
ICON="/usr/share/icons/picarec.png"

# Translations
if [ "$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=picarec
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=$"Recover deleted files."
LDESCRIP=$"$TITLE is a tool to recover deleted files."

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

clean () {
if [ "$TMP_SEL_MP" = "Y" ] ; then umount "$SEL_MP" ; rmdir "$SEL_MP" ; fi
rm -f /tmp/selrec /tmp/fls_D.txt /tmp/fls_F.txt /tmp/icat.txt /tmp/sleuthkit.txt /tmp/sleuthkit_filename.txt /tmp/sleuthkit_path.txt /tmp/sleuthkit*
unset SEL SEL_MP SEL_DEV SEL_DEV_FORMAT SLEUTH_SEL_DEV_FORMAT SEL_DEV_MP DEST DEST_MP DEST_DEV DIRSLEUTH FILENAME RELPATH
}

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 recover deleted files.\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


### CLEAN ########################################

clean


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

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please, if you want to recover files from an external disk or removable device, ensure it is physically 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 ########################################

# lsblk - add inverse tree support (-s)  https://mirrors.kernel.org/pub/linux/utils/util-linux/v2.22/v2.22-ReleaseNotes	(Debian 8 "Jessie")

recparts () {

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

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 )
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 )
btrfs device scan ; BTRFSRAIDACTIVEPARTS=$(LANG=C btrfs filesystem show | sed ':a;N;$!ba;s|\n\t| |g' | grep -aEi "[a-zA-Z0-9]" | grep -aEi 'Total devices ' | grep -aEiv 'Total devices 1 ' | while read i ; do echo $i | sed 's| |\n|g' | grep -aE "^/dev/" | 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 | sed -n '2,$p' ; done | grep -aEi "[a-zA-Z0-9]" | sort -u )
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 )

RECPARTS=$(echo "$CRYPTACTIVEPARTS $LVMACTIVEPARTS $BTRFSRAIDACTIVEPARTS $MDADMACTIVEPARTS" | sed 's| |\n|g' | grep -aE "[a-zA-Z0-9]" | grep -aE "[a-z]" | sort )

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 [ "$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 [ "$BTRFSRAIDACTIVEPARTS" != "" ] ; then
btrfs device scan ; INFOBTRFSACTIVEPARTS=$(echo $"Partitions that are part of 'btrfs' RAID partitions systems:" ; LANG=C btrfs filesystem show | sed ':a;N;$!ba;s|\n\t| |g' | grep -aEi "[a-zA-Z0-9]" | grep -aEi 'Total devices ' | grep -aEiv 'Total devices 1 ' | while read i ; do echo $(echo $i | sed 's| |\n|g' | grep -aE "^/dev/" | 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 ; echo \\n )
else
INFOBTRFSACTIVEPARTS=""
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

}


selbypart () {

recparts

if [ "$RECPARTS" = "" ] ; then
	PARTLIST=$(lsblk -r -n -o KNAME,RM,TYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$1}' | sort -u )
	PARTLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$1"\t"$3}' | sort -u )
	# label is optional and may contain spaces
	PARTLISTEXTRAINFO=$(lsblk -r -n -o KNAME,TYPE,SIZE,LABEL,NAME,UUID | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | sort -u | while read i ; do printf "/dev/""$i ("$(find -L /dev/disk/by-id/ -samefile /dev/$(echo $i | sed 's| .*||g') | sort | tail -n 1 | sed 's|/dev/disk/by-id/||g')")\n" | grep -aE "[0-9] " | sed 's| |     |1' ; done )
else
	PARTLIST=$(lsblk -r -n -o KNAME,RM,TYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$1}' | sort -u | grep -aEv "$(echo "$RECPARTS" | tr "\n" " " | tr " " "|" | sed 's:|:[^a-zA-Z0-9/-]|:g' | sed 's:|$::g')" )
	PARTLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$1"\t"$3}' | sort -u | grep -aEv "$(echo "$RECPARTS" | tr "\n" " " | tr " " "|" | sed 's:|:[^a-zA-Z0-9/-]|:g' | sed 's:|$::g')" )
	# label is optional and may contain spaces
	PARTLISTEXTRAINFO=$(lsblk -r -n -o KNAME,TYPE,SIZE,LABEL,NAME,UUID | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | sort -u | while read i ; do printf "/dev/""$i ("$(find -L /dev/disk/by-id/ -samefile /dev/$(echo $i | sed 's| .*||g') | sort | tail -n 1 | sed 's|/dev/disk/by-id/||g')")\n" | grep -aEv "$(echo "$RECPARTS" | tr "\n" " " | tr " " "|" | sed 's:|:[^a-zA-Z0-9/-]|:g' | sed 's:|$::g')" | grep -aE "[0-9] " | sed 's| |     |1' ; done )
fi

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

#SEL=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Please select the removable device or disk partition where were the files that you want to recover.\n\nAvailable devices:\n$PARTLISTEXTRAINFO\n\nIf you don't know which one is, use a file manager (thunar, pcmanfm, konqueror, dolphin, caja,...) or a partition manager (gparted,...) to search it.\n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)\n\n${INFOCRYPTACTIVEPARTS}${INFOLVMACTIVEPARTS}${INFOBTRFSACTIVEPARTS}${INFOMDADMACTIVEPARTS}" $H $W $LH $COLUMN $COLUMN $PARTLISTSIZE | head -n 1 )

SEL=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Please select the removable device or disk partition where were the files that you want to recover.\n\nAvailable devices:\n$PARTLISTEXTRAINFO\n\nIf you don't know which one is, use a file manager (thunar, pcmanfm, konqueror, dolphin, caja,...) or a partition manager (gparted,...) to search it.\n\n(1 GB = 1000 MB; 1 GiB = 1024 MiB)" $H $W $LH $COLUMN $COLUMN $PARTLISTSIZE | head -n 1 )

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

if [ ! -e "$SEL" ] || [ "$( echo "$SEL" | grep -aEi "^/dev/" )" = "" ] ; then
	REFUN=sel_dialog
	input_error ; return
fi

SELUUID=$(lsblk -r -n -o UUID $SEL | head -n 1 )
if [ "$SELUUID" = "" ] ; then SELUUID=$(blkid -o value -s UUID $SEL | head -n 1 | sed 's|/dev/disk/by-uuid/||g') ; fi
if [ "$SELUUID" = "" ] ; then SELUUID=$(find -L /dev/disk/by-uuid/ -samefile $SEL | head -n 1 | sed 's|/dev/disk/by-uuid/||g') ; fi
SELID=$(find -L /dev/disk/by-id/ -samefile $SEL | sort | tail -n 1 )
SEL_DEV="$SEL"
SEL_MP=$(lsblk -r -n -o MOUNTPOINT "$SEL")
## $SEL_DEV may not be mounted and therefore there is no $SEL_MP
#if [ "$SEL_MP" = "" ] ; then
#	TMP_SEL_MP="Y"
#	SEL_MP=/tmp/${CNAME}_$(echo "$SEL_DEV" | sed 's|/dev/||g' | sed 's|/|_|g')_$(date +%Y%m%d_%H%M%S)
#	mkdir -pv "$SEL_MP"
#	mount -o ro "$SEL_DEV" "$SEL_MP"
#	if [ "$SEL_MP" != "$(lsblk -r -n -o MOUNTPOINT "$SEL")" ] ; then
#		check_exit
#	fi
#fi

}


selbydir () {

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

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

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

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

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

}


sel_dialog () {

SELBYPART=$"Select removable device or disk partition"

SELBYDIR=$"Select folder/directory"

STOPNOW=$"Stop now"

OPT=$($DIALOG $WICON $WTITLE "$TITLE" $MONOLIST $WTEXT $"Please select the removable device, disk partition or folder/directory where were the files that you want to recover.\n" $H $W $LH $COLUMN $COLUMN "$SELBYPART" " " "$SELBYDIR" " " "$STOPNOW" " "  | head -n 1 )

if [ "$?" -ne 0 ] || [ "$OPT" = "" ] ; then
	clean
	exit 0
elif [ "$OPT" = "$STOPNOW" ] ; then
	clean
	exit 0
elif [ "$OPT" = "$SELBYPART" ] ; then
	selbypart
elif [ "$OPT" = "$SELBYDIR" ] ; then
	selbydir
else
	REFUN=sel_dialog
	input_error ; return
fi

}

sel_dialog

echo "SEL=\"${SEL}\"" | tee -a /tmp/selrec
echo "SEL_DEV=\"${SEL_DEV}\"" | tee -a /tmp/selrec
echo "SEL_MP=\"${SEL_MP}\""   | tee -a /tmp/selrec


#FILENAME=$($DIALOG $WICON $WTITLE "$TITLE" $WRITE $WTEXT $"If you want to recover a specific file, you can write its name below, otherwise leave it blank.\n\n(If you doubt, it is recommended to leave it blank, because generic searches may provide better results than specific ones.)\n" $H $W)


dest_dialog () {
	
	PREDEST=$($DIALOG $WICON $WTITLE $"Please select the folder/directory to dump the recovered files (default is /tmp/$CNAME )" $DSEL /tmp/ $H $W)

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

	if [ "$PREDEST" = "" ] || [ "$PREDEST" = "/tmp" ] || [ "$PREDEST" = "/tmp/" ] ; then
		PREDEST=/tmp/"$CNAME"_"$(date +%Y%m%d_%H%M%S)"
	fi


# Check: The destination folder/directory (the folder/directory to dump the recovered files) cannot be within the folder/directory to recover
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 recovered files cannot be within the folder/directory to recover." $H $W
		dest_dialog
	fi
fi


# Check: The destination folder/directory should be empty, no?
if [ -e "$PREDEST" ] ; then
if [ "$( ls -A "$PREDEST" )" != "" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"$PREDEST is not empty (this can make confusing the subsequent revision of the recovered files, but it does not affect the recovery itself).\n\nDo you want to use $PREDEST as the folder/directory to dump the recovered files?\n\n(If you want you can erase the content of the folder/directory before continuing)." $H $W

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

}

dest_dialog

DEST=$(echo "$PREDEST")
echo "DEST=\"${DEST}\"" | tee -a /tmp/selrec

if [ ! -d "$DEST" ] ; then
mkdir -pv "$DEST"
fi

cd "$DEST"

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


### PATH RELATIVE TO DEV ########################################

SEL_DEV_MP=$(lsblk -r -n -o MOUNTPOINT "$SEL_DEV")

RELPATH=$(echo "$SEL_MP" | sed "s|^$SEL_DEV_MP||g" | sed "s|^/||g")

echo "RELPATH=\"${RELPATH}\"" | tee -a /tmp/selrec


### DEVICE FORMAT ########################################

SEL_DEV_FORMAT=$(lsblk -r -n -o FSTYPE $SEL_DEV )

echo "SEL_DEV_FORMAT=$SEL_DEV_FORMAT"

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi ext )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="ext"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi fat )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="fat"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi ntfs )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="ntfs"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi iso9660 )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="iso9660"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi hfs )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="hfs"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi ufs )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="ufs"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi raw )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="raw"
fi

if [ "$( echo $SEL_DEV_FORMAT | grep -aEi swap )" != "" ] ; then
SLEUTH_SEL_DEV_FORMAT="swap"
fi


### ALL OK ? ########################################

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

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


### PREPARING ########################################

# pmount is only for removable (not internal) devices that mount in /media, and the official stable version does not support btrfs, nilfs2, exfat,...

if [ "$SELID" != "" ] ; then
	if [ "$SELUUID" != "" ] ; then
		if [ "$(cat /etc/mtab | grep -aEi "^$SEL_DEV |^$SELID |^/dev/disk/by-uuid/$SELUUID |^UUID=$SELUUID " | awk '{print $4}' | sed 's|,|\n|g' | grep -aE "^rw$")" != "" ] ; then
			$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"The general recommendation is that the device is not mounted in write mode.\n\nDo you want to unmount $SEL_DEV ?\n" $H $W
			if [ "$?" -eq 0 ] ; then
				mount -o remount,ro "${SEL_DEV}" "${SEL_DEV_MP}"
			fi
		fi
	else
		if [ "$(cat /etc/mtab | grep -aEi "^$SEL_DEV |^$SELID " | awk '{print $4}' | sed 's|,|\n|g' | grep -aE "^rw$")" != "" ] ; then
			$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"The general recommendation is that the device is not mounted in write mode.\n\nDo you want to unmount $SEL_DEV ?\n" $H $W
			if [ "$?" -eq 0 ] ; then
				mount -o remount,ro "${SEL_DEV}" "${SEL_DEV_MP}"
			fi
		fi
	fi
else
	if [ "$SELUUID" != "" ] ; then
		if [ "$(cat /etc/mtab | grep -aEi "^$SEL_DEV |^/dev/disk/by-uuid/$SELUUID |^UUID=$SELUUID " | awk '{print $4}' | sed 's|,|\n|g' | grep -aE "^rw$")" != "" ] ; then
			$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"The general recommendation is that the device is not mounted in write mode.\n\nDo you want to unmount $SEL_DEV ?\n" $H $W
			if [ "$?" -eq 0 ] ; then
				mount -o remount,ro "${SEL_DEV}" "${SEL_DEV_MP}"
			fi
		fi
	else
		if [ "$(cat /etc/mtab | grep -aEi "^$SEL_DEV " | awk '{print $4}' | sed 's|,|\n|g' | grep -aE "^rw$")" != "" ] ; then
			$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"The general recommendation is that the device is not mounted in write mode.\n\nDo you want to unmount $SEL_DEV ?\n" $H $W
			if [ "$?" -eq 0 ] ; then
				mount -o remount,ro "${SEL_DEV}" "${SEL_DEV_MP}"
			fi
		fi
	fi
fi


### SLEUTHKIT ########################################

e_sleuthkit () {

	$DIALOG $WICON $WTITLE "$TITLE" $OK " " $WAIT  $WTEXT $"Please wait..." $H $W &
	PIDDIALOG=$( echo $! )

DIRSLEUTH=$(echo REC_"$CNAME"_$(date +%Y%m%d_%H%M%S))
mkdir -pv "$DIRSLEUTH"

#STARTPARTITION=$( mmls "$SEL_DEV" | grep -aE ^[0-9] | grep -aEiv 'Table|Unallocated' | awk '{print $3}' | head -n 1 )
fls -D -d -p -r "$SEL_DEV" -f "$SLEUTH_SEL_DEV_FORMAT" | tee /tmp/fls_D.txt
fls -F -d -p -r "$SEL_DEV" -f "$SLEUTH_SEL_DEV_FORMAT" | tee /tmp/fls_F.txt

cat /tmp/fls_D.txt | sed "s|.*\t||g" | while read i ; do mkdir -pv "$DEST"/"$DIRSLEUTH"/"$i" ; done
cat /tmp/fls_F.txt | sed "s|.*\t||g" | grep -aEio ".*/" | while read i ; do mkdir -pv "$DEST"/"$DIRSLEUTH"/"$i" ; done

cat /tmp/fls_F.txt | while read i ; do echo "$i" | awk '{print "icat -f ""'"$SLEUTH_SEL_DEV_FORMAT"'"" -r ""'"$SEL_DEV"'"$2" > ""'"'"'""'"$DEST"'""/""'"$DIRSLEUTH"'""/"$3"'"'"'"}' FS='*|\t' | tee /tmp/icat.txt ; done
cat /tmp/icat.txt | sed 's|: > | > |g' | tr "\t" "/" | sed 's|(realloc)||g' | sed 's|//|/|g' | tee /tmp/sleuthkit.txt

	kill $PIDDIALOG 2>/dev/null

if [ "$FILENAME" != "" ] ; then
	cat /tmp/sleuthkit.txt | grep -a "$FILENAME" | tee /tmp/sleuthkit_filename.txt
	chmod +x /tmp/sleuthkit_filename.txt
	TT=$"Trying to recover $FILENAME... Please wait..." ; COM="bash /tmp/sleuthkit_filename.txt" ; TERMINAL ; rm -f /tmp/sleuthkit_filename.txt
	#sh /tmp/sleuthkit_filename.txt
elif [ "$RELPATH" != "" ] ; then
	cat /tmp/sleuthkit.txt | grep -a "$RELPATH" | tee /tmp/sleuthkit_path.txt
	chmod +x /tmp/sleuthkit_path.txt
	TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sleuthkit_path.txt" ; TERMINAL ; rm -f /tmp/sleuthkit_path.txt
	#sh /tmp/sleuthkit_path.txt
else
	chmod +x /tmp/sleuthkit.txt
	TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sleuthkit.txt" ; TERMINAL ; rm -f /tmp/sleuthkit.txt
	#sh /tmp/sleuthkit.txt
fi

}


### UNDELETE ########################################

if [ "$SEL_DEV_FORMAT" = "ext3" ] || [ "$SEL_DEV_FORMAT" = "ext4" ] ; then
	
	if [ "$(command -v extundelete)" != "" ] ; then
		if [ "$FILENAME" != "" ] ; then
			echo "extundelete $SEL_DEV --restore-file \"$FILENAME\"" > /tmp/sh_extundelete ; chmod +x /tmp/sh_extundelete ; TT=$"Trying to recover $FILENAME... Please wait..." ; COM="bash /tmp/sh_extundelete" ; TERMINAL ; rm -f /tmp/sh_extundelete
			#extundelete "$SEL_DEV" --restore-file "$FILENAME"
		elif [ "$RELPATH" != "" ] ; then
			echo "extundelete $SEL_DEV --restore-directory \"$RELPATH\"" > /tmp/sh_extundelete ; chmod +x /tmp/sh_extundelete ; TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_extundelete" ; TERMINAL ; rm -f /tmp/sh_extundelete
			#extundelete "$SEL_DEV" --restore-directory "$RELPATH"
		else
			TT=$"Trying to recover $SEL... Please wait..." ; COM="extundelete $SEL_DEV --restore-all" ; TERMINAL
			#extundelete "$SEL_DEV" --restore-all
		fi
		mv RECOVERED_FILES EXT_REC_"$CNAME"_$(date +%Y%m%d_%H%M%S)
	fi

	if [ "$(command -v ext4magic)" != "" ] ; then
		if [ "$FILENAME" != "" ] ; then
			echo "ext4magic $SEL_DEV -a 0 -b 1000000000 -r -f \"$FILENAME\"" > /tmp/sh_ext4magic ; chmod +x /tmp/sh_ext4magic ; TT=$"Trying to recover $FILENAME... Please wait..." ; COM="bash /tmp/sh_ext4magic" ; TERMINAL ; rm -f /tmp/sh_ext4magic
			#ext4magic "$SEL_DEV" -a 0 -b 1000000000 -r -f "$FILENAME"
		elif [ "$RELPATH" != "" ] ; then
			echo "ext4magic $SEL_DEV -a 0 -b 1000000000 -r -f \"$RELPATH\"" > /tmp/sh_ext4magic ; chmod +x /tmp/sh_ext4magic ; TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_ext4magic" ; TERMINAL ; rm -f /tmp/sh_ext4magic
			#ext4magic "$SEL_DEV" -a 0 -b 1000000000 -r -f "$RELPATH"
		else
			TT=$"Trying to recover $SEL... Please wait..." ; COM="ext4magic -m $SEL_DEV" ; TERMINAL
			#ext4magic -m "$SEL_DEV"
		fi
		mv RECOVERDIR EXT_REC2_"$CNAME"_$(date +%Y%m%d_%H%M%S)
	fi
	
	if [ "$(command -v fls)" != "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please review the content of $DEST \n\nIf the recovery was not satisfactory, $TITLE can try to recover the files with an alternative recovery method. Do you want to do it?" $H $W
		
		if [ "$?" -eq 0 ] ; then
		e_sleuthkit
		fi
	fi

elif [ "$SEL_DEV_FORMAT" = "btrfs" ] ; then

	if [ "$(command -v btrfs)" != "" ] ; then
		# dump BTRFS.
		DIRBTRFS=$(echo BTRFS_REC_"$CNAME"_$(date +%Y%m%d_%H%M%S))
		
		mkdir -pv $DIRBTRFS

		if [ "$FILENAME" != "" ] ; then
			FILENAME=$(ls -p "$FILENAME" | grep -aEio ".*/")
			PREREGEX=$(echo "$FILENAME" | sed -e 's:^/::g' -e 's:\\:\\\\:g' -e 's:\.:\\.:g' -e 's:\+:\\+:g' -e 's:|:\\|:g' -e 's:(:\\(:g' -e 's:):\\):g' -e 's:\[:\\[:g' -e 's:\]:\\]:g' -e 's:{:\\{:g' -e 's:\}:\\}:g' -e 's:\*:\\*:g' -e 's:\?:\\?:g' -e 's: :\\ :g' -e 's:/:(|/:g' ) ; NPAR=$(echo "$PREREGEX" | grep -aEo \(\|/ | grep -a -c ^) ; REGEX=$(echo \'^/\(\|$(echo "$PREREGEX")\.\*$(printf %.s')' $(seq $(expr $NPAR + 1 )))\$\')
#cat << EOF > /tmp/sh_btrfs
cat > /tmp/sh_btrfs <<EOF
btrfs-find-root -a $SEL_DEV 2>&1 | grep -aE "^Well" | cut -d ' ' -f 3 | sed 's|[a-zA-Z\(\[\{\:].*||g' | while read i ; do btrfs restore -mxSi -t "\$i" --path-regex $REGEX $SEL_DEV $DIRBTRFS ; done
EOF
		chmod +x /tmp/sh_btrfs
		TT=$"Trying to recover $FILENAME... Please wait..." ; COM="bash /tmp/sh_btrfs" ; TERMINAL ; rm -f /tmp/sh_btrfs
		elif [ "$RELPATH" != "" ] ; then
			RELPATH="$RELPATH"/
			PREREGEX=$(echo "$RELPATH" | sed -e 's:^/::g' -e 's:\\:\\\\:g' -e 's:\.:\\.:g' -e 's:\+:\\+:g' -e 's:|:\\|:g' -e 's:(:\\(:g' -e 's:):\\):g' -e 's:\[:\\[:g' -e 's:\]:\\]:g' -e 's:{:\\{:g' -e 's:\}:\\}:g' -e 's:\*:\\*:g' -e 's:\?:\\?:g' -e 's: :\\ :g' -e 's:/:(|/:g' ) ; NPAR=$(echo "$PREREGEX" | grep -aEo \(\|/ | grep -a -c ^) ; REGEX=$(echo \'^/\(\|$(echo "$PREREGEX")\.\*$(printf %.s')' $(seq $(expr $NPAR + 1 )))\$\')
#cat << EOF > /tmp/sh_btrfs
cat > /tmp/sh_btrfs <<EOF
btrfs-find-root -a $SEL_DEV 2>&1 | grep -aE "^Well" | cut -d ' ' -f 3 | sed 's|[a-zA-Z\(\[\{\:].*||g' | while read i ; do btrfs restore -mxSi -t "\$i" --path-regex $REGEX $SEL_DEV $DIRBTRFS ; done
EOF
		chmod +x /tmp/sh_btrfs
		TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_btrfs" ; TERMINAL ; rm -f /tmp/sh_btrfs
		else
#cat << EOF > /tmp/sh_btrfs
cat > /tmp/sh_btrfs <<EOF
btrfs-find-root -a $SEL_DEV 2>&1 | grep -aE "^Well" | cut -d ' ' -f 3 | sed 's|[a-zA-Z\(\[\{\:].*||g' | while read i ; do btrfs restore -mxSi -t "\$i" $SEL_DEV $DIRBTRFS ; done
EOF
		chmod +x /tmp/sh_btrfs
		TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_btrfs" ; TERMINAL ; rm -f /tmp/sh_btrfs
		fi
	fi
	
	if [ "$(command -v fls)" != "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please review the content of $DEST \n\nIf the recovery was not satisfactory, $TITLE can try to recover the files with an alternative recovery method. Do you want to do it?" $H $W
		
		if [ "$?" -eq 0 ] ; then
		e_sleuthkit
		fi
	fi

elif [ "$SEL_DEV_FORMAT" = "ntfs" ] ; then

	if [ "$(command -v ntfsundelete)" != "" ] ; then

		DIRNTFS=$(echo NTFS_REC_"$CNAME"_$(date +%Y%m%d_%H%M%S))

		mkdir -pv $DIRNTFS

		if [ "$FILENAME" != "" ] ; then
			echo "ntfsundelete $SEL_DEV -f -u --optimistic -d $DIRNTFS -m \"$FILENAME\"" > /tmp/sh_ntfsundelete ; chmod +x /tmp/sh_ntfsundelete ; TT=$"Trying to recover $FILENAME... Please wait..." ; COM="bash /tmp/sh_ntfsundelete" ; TERMINAL ; rm -f /tmp/sh_ntfsundelete
			#ntfsundelete "$SEL_DEV" -f -u --optimistic -d $DIRNTFS -m "$FILENAME"
		elif [ "$RELPATH" != "" ] ; then
			echo "ntfsundelete $SEL_DEV -f -u --optimistic -d $DIRNTFS -m \"$RELPATH\"" > /tmp/sh_ntfsundelete ; chmod +x /tmp/sh_ntfsundelete ; TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_ntfsundelete" ; TERMINAL ; rm -f /tmp/sh_ntfsundelete
			#ntfsundelete "$SEL_DEV" -f -u --optimistic -d $DIRNTFS -m "$RELPATH"
		else
			echo "ntfsundelete $SEL_DEV -u --optimistic -d $DIRNTFS -m \"*\"" > /tmp/sh_ntfsundelete ; chmod +x /tmp/sh_ntfsundelete ; TT=$"Trying to recover $SEL... Please wait..." ; COM="bash /tmp/sh_ntfsundelete" ; TERMINAL ; rm -f /tmp/sh_ntfsundelete
			#ntfsundelete "$SEL_DEV" -u --optimistic -d $DIRNTFS -m "*"
		fi
	fi

	if [ "$(command -v fls)" != "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please review the content of $DEST \n\nIf the recovery was not satisfactory, $TITLE can try to recover the files with an alternative recovery method. Do you want to do it?" $H $W
		
		if [ "$?" -eq 0 ] ; then
		e_sleuthkit
		fi
	fi

elif [ "$SEL_DEV_FORMAT" = "fat" ] || [ "$SEL_DEV_FORMAT" = "vfat" ] ; then

	if [ "$(command -v fatcat)" != "" ] ; then

		DIRFAT=$(echo FAT_REC_"$CNAME"_$(date +%Y%m%d_%H%M%S))

		mkdir -pv $DIRFAT

		TT=$"Trying to recover $SEL... Please wait..." ; COM="fatcat $SEL_DEV -x $DIRFAT -d" ; TERMINAL
		#fatcat $SEL_DEV -x $DIRFAT -d
			
	fi

	if [ "$(command -v fls)" != "" ] ; then
		$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please review the content of $DEST \n\nIf the recovery was not satisfactory, $TITLE can try to recover the files with an alternative recovery method. Do you want to do it?" $H $W
		
		if [ "$?" -eq 0 ] ; then
		e_sleuthkit
		fi
	fi



elif [ "$SLEUTH_SEL_DEV_FORMAT" != "" ] ; then

	if [ "$(command -v fls)" != "" ] ; then
		e_sleuthkit
	fi

else

	echo "No format?"
	echo "SEL_DEV_FORMAT=$SEL_DEV_FORMAT"
	echo "SLEUTH_SEL_DEV_FORMAT=$SLEUTH_SEL_DEV_FORMAT"

fi

if [ "$(command -v photorec)" != "" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"Please review the content of $DEST \n\nIf the recovery was not satisfactory, you can try to recover the files of $SEL with a 'deeper' recovery method but this method is complicated and it does not preserve the file names nor folders/directories (and neither the folders/directories hierarchy). Do you want to do it?" $H $W

		if [ "$?" -eq 0 ] ; then
		exec >/dev/tty
		TT="$TITLE" ; COM="photorec $SEL_DEV" ; TERMINAL
		if [ "$DEBUG" != "N" ] ; then
			exec > >(tee -a "$ERRORLOG") 2>&1
		fi
		fi
fi


### CHANGE PERMISIONS ########################################

# chmod 777 "$DEST"
# find "$DEST"/ -type f | while read i ; do chmod 666 "$i" ; done
# find "$DEST"/ -type d | while read i ; do chmod 777 "$i" ; done
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 if [ "$(id -nu $i)" != "" ] ; then chown -R $(id -nu $i):$(id -ng $i) "$DEST" ; else chown -R 1000:1000 "$DEST" ; fi ; break ; fi ; done


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

$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"$TITLE finished.\n\nPlease review the content of $DEST \n\nIf the recovery was not satisfactory, you can rerun $TITLE selecting less specific options.\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
