#!/bin/bash
#
# cs_check_lsbinit
#
# (c) 2013 SUSE Linux GmbH, Germany. Author: L.Pinne.
# GNU Public License. No warranty.
#
# Version : 2013-08-21
#
#set -x

EXE=$0
ERR=/dev/null
# TODO use config file for patterns and number
# TODO why returns -c 95+20 but -o 122+4 ?
# TODO use insserv to check for lsb compliance ""

function check_scripts() {
  OK=0; KO=0
  for f in /etc/init.d/* ; do
	RC=0
	if [ -f $f -a -x $f ]; then
		m=$( grep -c -e '^#\![[:blank:]]\?/bin/.*sh' \
 		-e '^### BEGIN INIT INFO' \
		-e '^#[[:blank:]]\{1\}Provides:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Default-Start:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Default-Stop:[[:blank:]]\?' \
		-e '^#[[:blank:]]\{1\}Required-Start:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Required-Stop:[[:blank:]]\?' \
		-e '^### END INIT INFO' \
		-e '[[:blank:]]\+/etc/rc.status' \
		-e '[[:blank:]]\?start\\*\?)' \
		-e '[[:blank:]]\?stop\\*\?)' \
		-e '[[:blank:]]\?status\\*\?)' \
		$f 2>>$ERR )
	# TODO check LSB if only one blank is allowed after # and after :
	# TODO better regex for start
	# 	|start start| " "start ^start start"*"
	# TODO see smt, rpmconfigcheck
	# TODO nfs has no start), but start-no| start-yes|
	# TODO better regex for stop,status
	# TODO LSB also describes: 	restart , force-reload
	# TODO LSB uses:		/lib/lsb/init-functions
	# TODO runlevel 4 is reserved for local use
	#
		# $m should equal to num of grep patterns $LM
		LM=12
		if [ $m -lt $LM ]; then
			KO=$[ $KO + 1 ]
			echo -n "$f : $m/$LM"
			echo
	 	else	OK=$[ $OK + 1 ]
		fi
	fi
  done
  echo "OK: $OK"
  echo "KO: $KO"
}


function show_script() {
	f=$1
	# TODO common search function
	# TODO show missing

	echo "=== need:"
	echo '^#\![[:blank:]]\?/bin/.*sh'
	echo '^### BEGIN INIT INFO'
	echo '^#[[:blank:]]\{1\}Provides:[[:blank:]]\+'
	echo '^#[[:blank:]]\{1\}Default-Start:[[:blank:]]\+'
	echo '^#[[:blank:]]\{1\}Default-Stop:[[:blank:]]\?'
	echo '^#[[:blank:]]\{1\}Required-Start:[[:blank:]]\+' \
	echo '^#[[:blank:]]\{1\}Required-Stop:[[:blank:]]\?' \
	echo '^### END INIT INFO'
	echo "[[:blank:]]\+/etc/rc.status"
	echo "[[:blank:]]\?start\\*\?)"
	echo "[[:blank:]]\?stop\\*\?)"
	echo "[[:blank:]]\?status\\*\?)"
	echo "==="
	echo "=== found:"
	grep -e '^#\![[:blank:]]\?/bin/.*sh' \
		-e '^### BEGIN INIT INFO' \
		-e '^#[[:blank:]]\{1\}Provides:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Default-Start:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Default-Stop:[[:blank:]]\?' \
		-e '^#[[:blank:]]\{1\}Required-Start:[[:blank:]]\+' \
		-e '^#[[:blank:]]\{1\}Required-Stop:[[:blank:]]\?' \
		-e '^### END INIT INFO' \
		-e '[[:blank:]]\+/etc/rc.status' \
		-e '[[:blank:]]\?start\\*\?)' \
		-e '[[:blank:]]\?stop\\*\?)' \
		-e '[[:blank:]]\?status\\*\?)' \
	$f 2>>$ERR
	echo "==="
	rpm -qf $f 2>>$ERR
}


function foreign_package() {
  OK=0; KO=0; NO=0
  for f in /etc/init.d/* ; do
	RC=0
	if [ -f $f -a -x $f ]; then
		p=$(rpm -qf $f 2>>$ERR) || RC=1
	fi
	if [ $RC -ne 0 ]; then
		NO=$[ $NO + 1 ]
	else
		N=$( zypper se --details -t package $(rpm -qi $p |\
		awk '$1=="Name"{print $3}') |\
		awk '$1=="i"&&NF==12 {print "no_repo: "$3}' )
	fi
#	if [ $RC -eq 0 ]; then
#		OK=$[ $OK + 1 ]
#	else	
#		KO=$[ $KO + 1 ]
#		echo "no_repo: $p"
#	fi	
  done
  echo $N
  echo "NO: $NO"
  echo "OK: $OK"
  echo "KO: $KO"
}


function orphan_script() {
  OK=0; KO=0
  for f in /etc/init.d/* ; do
	RC=0
	if [ -f $f -a -x $f ]; then
		p=$(rpm -qf $f 2>>$ERR) || RC=1
	fi
	if [ $RC -ne 0 ]; then
		KO=$[ $KO + 1 ]
		echo -n "no_RPM: $f"
		echo
	else
		OK=$[ $OK + 1 ]
	fi
  done
  echo "OK: $OK"
  echo "KO: $KO"
}


function help() {
	echo
	echo "$(basename $EXE) --show /path/to/script" 
	echo "$(basename $EXE) --check | --orphan | --foreign"
	echo "$(basename $EXE) --version | --help"
	echo
	echo "please call as root."
	echo
	echo "see also init.d(7) and"
	echo "http://refspecs.linux-foundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html"
	echo "this script is quite beta."
}


# main()
case $1 in
	-v|--version)
		echo -n "$(basename $EXE) "
		head -11 $EXE | grep "^# Version: "
		exit
	;;
	-s|--show|--show_script)
		test $UID -gt 0 && echo "please call as root." && exit
		show_script $2
		exit
	;;
	-c|--show|--check_scripts)
		test $UID -gt 0 && echo "please call as root." && exit
		check_scripts
		exit
	;;
	-f|--foreign|--foreign_package)
		test $UID -gt 0 && echo "please call as root." && exit
		foreign_package
		exit
	;;
	-o|--orphan|--orphan_script)
		test $UID -gt 0 && echo "please call as root." && exit
		orphan_script
		exit
	;;
	*)
		help
		exit
	;;
esac
#
