#!/bin/bash
#
# File: /usr/local/bin/diskspace
#
# listet Festplatten- und Speicherstickbelegung auf, auch mit Balken.
#
#    Copyright (C) 2014  Ingo Kaesmann
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#
# Script template: 0.3.6
#
# Exit codes:
# 0 = OK
# 1 = Error in parameters
# 2 = Error in configfile, configfile old or not found
# 3 = Library old or not found
# 8 = Error in other file or other file not found
# 20= Another instance of program is running
# 99= Other error
##############################################################################
# SOURCE STANDARD FILES

. /usr/local/etc/main-inka-sh.conf			# main config
. $LLIBDIR/lib-inka-std.sh				# functions standard
#test -e /usr/local/etc/x.conf && . /usr/local/etc/x.conf	# global config
#test -e ~/.$(basename $0)rc && . ~/.$(basename $0)rc	# personal config
#test -e ~/.xrc && . ~/.xrc				# local config
##############################################################################
# DECLARATION OF VARIABLES

# STRINGS
pkgname=inka-utilities					# package name
lib_inka_std_sh_needed=1.3.6				# standard lib version
conf_file_needed=0.0.1					# conf file version
#----------------------- end of variables to configure -----------------------
version=$(grep "^VERSION" $PROGREG/$pkgname.inf | cut -f 2)	# version
scriptname=$(basename $0)				# name of script
tempfile=$TEMPDIR/$scriptname.$UID.$$.tmp		# temporary file
infolog="logger -p user.info -t $scriptname --"		# log info messages
errlog="logger -p user.err -t $scriptname -- ERROR:"	# log error messages
debuglog="logger -p user.debug -t $scriptname -- DEBUG:" # log debug messages
debug=no						# debug=yes/no
verbose=""						# verbose=""/-q/-v
opt_found=no						# opt_found=yes/no
opt=""							# option
#------------------------- end of standard variables -------------------------
# var=""						#

# NUMBERS
err=0							# exit code
##############################################################################
# FUNCTIONS

function show_help ()
{
# Show help
# Uses: cat
# Return codes: standard

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG show_help: $# $@" >&2
	#$debuglog show_help: $# $@
fi

cat <<EOT

Aufruf: $scriptname [OPTION]...
Listet die Festplattenbelegung auf, auch mit Balkengrafik.

        -b      Angabe in Byte
        -k      Angabe in kB
        -m      Angabe in MB
        -g      Angabe in GB
        -t      Angabe in TB
-h, --help      Hilfe anzeigen und beenden
 --version      Versionsinformationen anzeigen und beenden
   --debug      Debug-Modus benutzen

Wenn ohne Option angegeben, Anzeige des Platzes mindestens zweistellig mit automatischem Praefix.
EOT
return
}

#-----------------------------------------------------------------------------
function show_config ()
{
# Show configuration of program
# Uses: cat, cut, grep
# Return codes: standard

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG show_config: $# $@" >&2
	#$debuglog show_config: $# $@
fi

cat <<EOT

var-Erklaerung:
$var

Programm wird zu folgenden Zeiten aufgerufen:
EOT
grep "&&" /etc/cron.d/xyz.cron | cut -f 1

return
}
#-----------------------------------------------------------------------------
function main_proc ()
{
# Show file system partition, whole, used and free space by byte or whith
# prefix. Used and free space by % too. And show grafic bar.
# Par1 = -b or nothing
# Uses: cat, clear, df, echo, rm, wc
# Return codes: standard

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG main_proc: $# $@" >&2
	#$debuglog main_proc: $# $@
fi

local p1 line pn wsb usb fsb mp wsdB usdB fsdB ws us fs up fp lastline n
p1="$1"		# -b, when given
line=""		# line
pn=""		# partition name
wsb=""		# whole space (KiB)
usb=""		# used space  (KiB)
fsb=""		# free space  (KiB)
mp=""		# mount point
wsdB=0		# whole space (Byte)
usdB=0		# used space (Byte)
fsdB=0		# free space (Byte)
ws=0		# whole space and prefix
us=0		# used space and prefix
fs=0		# free space and prefix
up=0		# used space (%)
fp=0		# free space (%)
lastline=0	# number of lines
n=0		# loop counter

df | grep "/dev/sd" | sort > $tempfile
lastline=$(cat $tempfile | wc -l)
clear
echo ' ______________________________________________________________________________________________________'

while [ $n -lt $lastline ]; do
	let n++
	line=$(Read_Lines $tempfile $n $n)
	pn=$(echo $line | cut -d " " -f 1 | cut -d "/" -f 3)
	wsb=$(echo $line | cut -d " " -f 2)
	wsdB=$(($wsb*1024))
	ws=$(setting_prefix $wsdB $p1)
	usb=$(echo $line | cut -d " " -f 3)
	usdB=$(($usb*1024))
	us=$(setting_prefix $usdB $p1)
	fsb=$(echo $line | cut -d " " -f 4)
	fsdB=$(($fsb*1024))
	mp=$(echo $line | cut -d " " -f 6)
	fs=$(setting_prefix $fsdB $p1)
	up=$(echo $line | cut -d " " -f 5 | cut -d "%" -f 1)
	fp=$[100-${up}]
	echo '/                                                                                                      \'
	echo -e "                                                                                                       |\r\c"
	echo "| ${pn}: ${ws} gesamt, ${us} ($up%) belegt, ${fs} ($fp%) frei, ${mp}"
	echo '|                                                                                                      |'
	give_space_out $up $fp
	echo '\______________________________________________________________________________________________________/'
done
echo

rm -f $tempfile
return
}
#-----------------------------------------------------------------------------
function setting_prefix
{
# Detection prefix. If prefix not given, detection best prefix fo easy reading.
# Par1 = space in byte
# Par2 = -b, -k, -m, -g, -t (if given)
# Uses: echo
# Return codes: standard

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG setting_prefix: $# $@" >&2
	#$debuglog setting_prefix: $# $@
fi

local pf n a b
pf="$2"		# prefix if given (-b, -k, -m, -g, -t)
n=$1		# given number, outgoing number if prefix is B
a=0		# for counting for prefix
b=0		# outgoing number

if [ "$pf" == "-b" ]; then
	echo "$n B"				# space in B
elif [ "$pf" == "-k" ]; then
	b=$(($n/1000))
	echo "$b kB"				# space in kB
elif [ "$pf" == "-m" ]; then
	b=$(($n/1000000))
	echo "$b MB"				# space in MB
elif [ "$pf" == "-g" ]; then
	b=$(($n/1000000000))
	echo "$b GB"				# space in GB
elif [ "$pf" == "-t" ]; then
	b=$(($n/1000000000000))
	echo "$b TB"				# space in TB
else
	a=$(($n/10000000000000))
	if [ $a -gt 0 ]; then
		b=$(($n/1000000000000))
		echo "$b TB"			# space in TB
		return
	fi
	a=$(($n/10000000000))
	if [ $a -gt 0 ]; then
		b=$(($n/1000000000))
		echo "$b GB"			# space in GB
		return
	fi
	a=$(($n/10000000))
	if [ $a -gt 0 ]; then
		b=$(($n/1000000))
		echo "$b MB"			# space in MB
		return
	fi
	a=$(($n/10000))
	if [ $a -gt 0 ]; then
		b=$(($n/1000))
		echo "$b kB"			# space in kB
		return
	fi
	echo "$n B"				# space in B
fi

return
}
#-----------------------------------------------------------------------------
function give_space_out ()
{
# Print a line on stout that contains 100 chars of 2 different chars and the
# side characters of a box.
# Par1: Percent of Used space (max. 100)
# Par2: Percent of free space (max. 100)
# Print on stout
# Uses: echo
# Return codes: standard

if [ "$debug" == "yes" ]; then                          # debug
	echo "DEBUG give_space_out: $# $@" >&2
fi

local p1 p2 su tu sf tf
p1="$1"		# par1 - number of used-space characters
p2="$2"		# par2 - number of free-space characters
su='HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'	# 100 used-space characters
sf='----------------------------------------------------------------------------------------------------'	# 100 free-space characters
tu=''		# used-space characters
tf=''		# free-space characters

tu=${su:0:$p1}						# used characters
tf=${sf:0:$p2}						# free characters
echo "| ${tu}${tf} |"					# finished string

return
}
##############################################################################
# PARSE COMMANDLINE

# Read all options with args and all additional args into variables.
# Stop parsing after last parameter.
# Try to do a check on all parameters and version numbers.
# Handle options -h, -C and -V directly.
# Exit on error.

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG Parse Commandline: $# $@" >&2
	#$debuglog Parse Commandline: $# $@
fi

# get options and options with arguments
while [ "${1:0:1}" == "-" ]; do				# get all options
	case "$1" in
	  -h|--help)	opt=-h;;			# option -h
	  --version)	opt=--v;; 			# option --version
#	  --show-config) opt=--s;;			# option --show-config
	  --debug)	debug=yes;;			# option --debug
	  -q|--quiet)	verbose=-q;;			# option -q
	  -v|--verbose)	verbose=-v;;			# option -v
#-------------------------- end of standard options --------------------------
	  -b|-k|-m|-g|-t)	opt="$1";;		# option -b,-k,-m,-g,-t
#	  -z)	opt_z=$1;;				# option -z
#	  -z)	opt_z=$1				# option -z + 1 arg
#		if [ "$#" -gt 1 ] & [ "${2:0:1}" != "-" ]; then	# par2 is 1.arg of opt_z
#			opt_z1=$2
#			shift				# shift option
#		else					# error no arg
#			if [ "$verbose" != -q ]; then
#				echo "Fehler - Wert fuer Option $1 fehlt!" >&2
#			else
#				$errlog arg for option $1 is missing
#			fi
#			exit 1
#		fi;;
	  *)	if [ "$verbose" != "-q" ]; then
			echo "Fehler - Option $1 falsch!" >&2	# error
		else
			$errlog unknown option $1
		fi
		exit 1;;
	esac
	shift			# shift option, or last argument for option
	opt_found=yes
done

# handle standard options -h, --v, --s
case "$opt" in
  -h)	show_help; exit 0;;					# show help
  --v)	echo "$scriptname (${pkgname}) $version"; exit 0;;	# show version
  --s)	show_config; exit 0;;					# show config
esac

# check arguments after options
case "$opt" in
#  -x|-y|-z)	if [ $# -eq 1 ]; then		# parameter count ok
#				arg1="$1"
#				shift
#		else				# error in param count
#			if [ "$verbose" != "-q" ]; then
#				echo "Fehler - Parameteranzahl falsch!" >&2
#			else
#				$errlog parameter count wrong
#			fi
#			exit 1
#		fi;;
  *)	if [ $# -ne 0 ]; then			# error in param count
		if [ "$verbose" != "-q" ]; then
			echo "Fehler - Parameteranzahl falsch!" >&2
		else
			$errlog parameter count
		fi
		exit 1
	fi;;
esac
##############################################################################
# CHECK LIBRARY AND CONFIG

# check library
Compare_Version $lib_inka_std_sh_needed $Lib_Inka_Std_Sh_Version
ret=$?						# (ret: 0,1,2,9,127)
if [ $ret -eq 1 ]; then		# needed lib-version higher than installed
	if [ "$verbose" != "-q" ]; then
		echo "Fehler - Programm benoetigt neuere Version von lib-inka-std.sh!" >&2
	else
		$errlog newer version of lib-inka-std.sh needed
	fi
	exit 3
elif [ $ret -eq 9 ] || [ $ret -eq 127 ]; then		# other error (version or lib missing)
	if [ "$verbose" != "-q" ]; then
		echo "Fehler - Versionspruefung von lib-inka-std.sh nicht moeglich!"
	else
		$errlog check of version of lib-inka-std.sh impossible
	fi
	exit 3
else					# check ok, reset $ret
	ret=0
fi

# check version of config files - set config var and program name!
#Compare_Version $conf_file_needed $Program_Conf
#Compare_Version $conf_file_needed $Program_Rc
ret=$?						# (ret: 0,1,2,9)
if [ $ret -eq 1 ]; then		# needed config-version higher than installed
	if [ "$verbose" != "-q" ]; then
		echo "Fehler - $scriptname benoetigt neuere Version der Konfig-datei!" >&2
	else
		$errlog newer version of conf file needed
	fi
	exit 2
elif [ $ret -eq 9 ]; then		# other error (version of conf file missing)
	if [ "$verbose" != "-q" ]; then
		echo "Fehler - Versionspruefung der Konfig-datei von $scriptname nicht moeglich!"
	else
		$errlog check of version of conf file impossible
	fi
	exit 2
else					# check ok, reset $ret
	ret=0
fi
##############################################################################
# MAINPROGRAM

if [ "$debug" == "yes" ]; then				# debug
	echo "DEBUG Main: $# $@" >&2
	#$debuglog Main: $# $@
fi

# Check what to do (initial options and args are removed from cmdline)
case "$opt" in
#  -x|-y)						# opt -xy
#	main_proc $arg1
#	err=$?;;
  ""|-b|-k|-m|-g|-t)				# no opt given, -b,-k,-m,-g,-t
	main_proc $opt
#	if [ "$verbose" != "-q" ]; then
#		echo "Fehler - Option fehlt!" >&2
#	else
#		$errlog option missing
#	fi
	err=1;;
esac

exit $err
