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

# picadrep
#
# Try to repair errors on a disk.
#
# 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 | dosfstools | e2fsprogs | 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, x11-xkb-utils
# Suggests: cryptsetup, dmsetup, lvm2, mdadm, mount, symlinks, tcplay


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

CNAME="picadrep"
VERSION="1.3.1"
TITLE="PicaDRep"
ICON="/usr/share/icons/picadrep.png"

# Translations
if [ "$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=picadrep
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=$"Try to repair errors on a disk."
LDESCRIP=$"$TITLE is a tool to try to repair errors on a 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

}


### 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" )
			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 try to repair errors on a disk.\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


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


### INFO ########################################

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

DMESGRO=$(dmesg | grep -aEi "remount.*read-only|remount.*ro|re-mount.*read-only|re-mount.*ro" | grep -aEv "Opt" | tail -n 10 )
SYSLOGRO=$(cat /var/log/syslog | grep -aEi "remount.*read-only|remount.*ro|re-mount.*read-only|re-mount.*ro" | grep -aEv "Opt" | tail -n 10 )
SYSLOGIO=$(cat /var/log/syslog | grep -aEi "I/O.*error|error.*I/O" | grep -aEiv laptop_mode | tail -n 10 )

	kill $PIDDIALOGINFO 2>/dev/null

echo "### mtab ##########"
cat /etc/mtab | grep -aE ^/dev/
echo "### DMESGRO ##########"
echo "$DMESGRO"
echo "### SYSLOGRO ##########"
echo "$SYSLOGRO"
echo "### SYSLOGIO ##########"
echo "$SYSLOGIO"
echo "#############"

if [ "$DMESGRO" != "" ] ; then
	TAILINFOLOG="$DMESGRO"
elif [ "$SYSLOGRO" != "" ] ; then
	TAILINFOLOG="$SYSLOGRO"
elif [ "$SYSLOGIO" != "" ] ; then
	TAILINFOLOG="$SYSLOGIO"
else
	TAILINFOLOG=""
fi

if [ "$TAILINFOLOG" != "" ] ; then
	$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"The most obvious disk error is an 'Input/Output Error' or 'I/O error' message. They can be perceived as strange failures when accessing, saving or modifying files on the disk or as unexpected failures when using operating system components and applications that usually work without problems, although these are generic errors that may be due to causes other than disk errors.\n\nPossible disk errors detected:\n\n$TAILINFOLOG\n" $H $W
else
	$DIALOG $WICON $WTITLE "$TITLE" $INFO  $WTEXT $"The most obvious disk error is an 'Input/Output Error' or 'I/O error' message. They can be perceived as strange failures when accessing, saving or modifying files on the disk or as unexpected failures when using operating system components and applications that usually work without problems, although these are generic errors that may be due to causes other than disk errors.\n\nNo disk errors were detected in a quick analysis.\n" $H $W
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

}

sel_dialog () {

recparts

if [ "$RECPARTS" = "" ] ; then
	PARTLIST=$(lsblk -r -n -o KNAME,RM,TYPE,FSTYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "/dev/"$1}' | sort -u | while read i ; do echo $PRES $i $POSTS ; done )
	PARTLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE,FSTYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "'"$PRES"'","/dev/"$1"\t("$3")","'"$POSTS"'"}' | sort -u )
	# label is optional and may contain spaces
	PARTLISTEXTRAINFO=$(lsblk -r -n -o KNAME,TYPE,SIZE,FSTYPE,LABEL,NAME,MOUNTPOINT | 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,FSTYPE,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')" | while read i ; do echo $PRES $i $POSTS ; done )
	PARTLISTSIZE=$(lsblk -r -n -o KNAME,RM,SIZE,TYPE,FSTYPE,NAME | grep -aEi ' part| crypt| raid| md| lvm| dm' | grep -aEiv '_rmeta_|_rimage_' | awk '{print "'"$PRES"'","/dev/"$1"\t("$3")","'"$POSTS"'"}' | 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,FSTYPE,LABEL,NAME,MOUNTPOINT | 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" $MULTIPLELIST $WTEXT $"Please select the disk partitions that you want to try to repair.\n\nIt is not possible to repair in-use (mounted) partitions, so this step is best done from a live system.\n\nAvailable partitions:\n$PARTLISTEXTRAINFO\n\nIf in doubt, leave all selected." $H $W $LH $COLUMN $COLUMN $COLUMN $PARTLISTSIZE | sed 's|(.*)||g' | sed 's|^TRUE||g')

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

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

}

sel_dialog


### SCRIPT TERMINAL ########################################

cat > /tmp/$CNAME <<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
#	exec > >(tee -a "$ERRORLOG") 2>&1 ; set -xv
#fi
#if [ "$DEBUG" != "N" ] ; then
#exec > >(tee -a "\$ERRORLOG") 2>&1
#echo "\$0" "\$*" >> "\$ERRORLOG"
#fi

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

SEL="$(echo "$SEL")"

for DEV in \$SEL ; do

	DEVFORMAT=\$(lsblk -r -n -o FSTYPE \$DEV )
	echo -e "\e[1;32m""============================== \$DEV \$DEVFORMAT""\e[0m"
	if [ "\$DEVFORMAT" != "" ] ; then
		if [ "\$DEVFORMAT" = "btrfs" ] ; then
			btrfs check --repair \$DEV
		elif [ "\$(command -v fsck.\$DEVFORMAT )" != "" ] ; then
			if [ "\$DEVFORMAT" = "ext4" ] || [ "\$DEVFORMAT" = "ext3" ] || [ "\$DEVFORMAT" = "ext2" ] || [ "\$DEVFORMAT" = "reiser" ] || [ "\$DEVFORMAT" = "reiserfs" ] ; then
				# fsck.ext{4,3,2} -> e2fsck
				fsck.\$DEVFORMAT -f \$DEV
			else
				# fsck.vfat -> fsck.fat
				fsck.\$DEVFORMAT \$DEV
			fi
		elif [ "\$(command -v \${DEVFORMAT}.fsck )" != "" ] ; then
			\${DEVFORMAT}.fsck \$DEV
		elif [ "\$(command -v \${DEVFORMAT}fix )" != "" ] || [ "\$(command -v \${DEVFORMAT}recover )" != "" ] ; then
			# ntfs
			\${DEVFORMAT}recover \$DEV
			\${DEVFORMAT}fix \$DEV
		elif [ "\$(echo \$DEVFORMAT | grep -aE "fs\$")" != "" ] && [ "\$(command -v \${DEVFORMAT}ck )" != "" ] ; then
			\${DEVFORMAT}ck \$DEV
		else
			false
		fi
	fi

done

sleep 3

EOF

chmod +x /tmp/$CNAME

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

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

echo $(date +%Y-%m-%d_%H:%M:%S) $"End"
rm -f /tmp/$CNAME


### REBOOT ########################################

$DIALOG $WICON $WTITLE "$TITLE" $QYN   $WTEXT $"As an additional or alternative step, it is also possible to try to repair partitions using a special reboot.\n\nDo you want to reboot the computer now? \n\nIt is recommended.\n" $H $W

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

	shutdown -F -r 5 &

fi


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

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