#!/bin/sh
# проверка целостности исполняемых файлов и файлов звукозаписи
# при обнаружении изменений в исполняемых файлах, записывается лог и возвращаем код 255
# при изменении файлов звукозаписи записывается лог изменений и возвращаем код 254
# код возврата 255 - АДИС не будет запускаться


USER_NAME="adis"
OUT=/var/log/$USER_NAME/"change_"$USER_NAME".diff"
if [ $LANG != "ru_RU.UTF-8" ] && [ $LANG != "ru_RU.utf8" ]; then
	CURRENT_CP="CP866"
fi
SPLIT_LINE=`seq -s "-" $(tput cols) | sed 's/[0-9]//g'`

# обязательная папка для проверки
BIN="/server/bin"

conv_cp() {
	if [ $CURRENT_CP ]; then
		echo $1 | iconv -fUTF-8 -t$CURRENT_CP
	else
		echo $1
	fi
}


create_diff() {
# path err_code access time

	if [ -z $3 ]; then
		access_list="full"
	else 
		access_list=$3
	fi

	ret_code=0
	log_name=`echo $1 | sed 's/\//_/g'`

	if [ ! -e /var/log/$USER_NAME ] ; then
		mkdir /var/log/$USER_NAME
		chmod 0700 /var/log/$USER_NAME
		chown "$USER_NAME""admin":$USER_NAME /var/log/$USER_NAME
	fi

	if [ ! -e /var/log/$USER_NAME/checksum ] ; then
		mkdir /var/log/$USER_NAME/checksum
		chmod 0700 /var/log/$USER_NAME/checksum
		chown "$USER_NAME""admin":$USER_NAME /var/log/$USER_NAME/checksum
	fi
		
	full_log_name=/var/log/$USER_NAME/checksum/"change"$log_name".log"
	if [ ! -f $full_log_name ]; then
		touch $OUT > /dev/null
		chmod 0600 $OUT
		chown "$USER_NAME""admin":$USER_NAME $OUT
	fi
	
	echo "# adis changelog: $1" > $full_log_name"1"
	chmod 0600 $full_log_name"1"
	chown "$USER_NAME""admin":$USER_NAME $full_log_name"1"

	if [ -z $4 ] ; then
		ctime=
	else
		ctime=" ! -ctime $4"
	fi

	ssl_error=
	for file_name in `find $1 -type f $ctime` ; do
#		openssl dgst -md5 $file_name >> $full_log_name"1"
		echo -n "MD5($file_name)= " >> $full_log_name"1"
		/server/bin/md5f < $file_name >> $full_log_name"1"
		if [ "$?" -ne "0" ] ; then
			ssl_error="$ssl_error|"`conv_cp "не удалось получить контрольную сумму файла $file_name"`
		fi
		echo "" >> $full_log_name"1"
	done;


	if [ -f $full_log_name ]; then
		# список всех измененных файлов
		file_list=`diff -u $full_log_name $full_log_name"1" | grep "[+-]MD5" | egrep -o '^[+-].+[(](.+)[)]'`
 
		uniq_list=
		res=`echo $ssl_error | tr "|" "\n"`
		for files in $file_list ; do
			bcnt=${#files}
			let bcnt=$bcnt-6
			cfile=${files:5:$bcnt} 
			cnt=`wc -w <<< $(echo $file_list | tr " " "\n" | grep $cfile)`
			sign=${files:0:1}
			echo $uniq_list | grep $cfile > /dev/null 2>&1
			
			if [ "$?" -eq "0" ] ; then
				continue
			fi

			uniq_list="$uniq_list $cfile"
			for access in `echo $access_list | tr "|" "\n"` ; do

				case $access in 
				"change")
						if [ "$cnt" -eq 2 ] ; then
							res="$res|"`conv_cp "изменения файла $cfile"`
						fi
						;;
				
				"create")
						if [ "$cnt" -eq 1 ] && [ "$sign" == "+" ] ; then
							res="$res|"`conv_cp "создание файла $cfile"`
						fi
						;;
				"delete")
						if [ "$cnt" -eq 1  ] && [ "$sign" == "-" ] ; then
							res="$res|"`conv_cp "удаление файла $cfile"`
						fi
						;;
		
				*)
						if [ "$cnt" -eq 2 ] ; then
							res="$res|"`conv_cp "изменения файла $cfile"`
						fi
						if [ "$cnt" -eq 1 ] && [ "$sign" == "+" ] ; then
							res="$res|"`conv_cp "создание файла $cfile"`
						fi
						if [ "$cnt" -eq 1 ] && [ "$sign" == "-" ] ; then
							res="$res|"`conv_cp "удаление файла $cfile"`
						fi
						;;
				esac
			done	

		done;
		
		if [ "$res" != "" ] ; then
			date >> $OUT
			echo $res| tr "|" "\n" >> $OUT
			echo $(seq -s "-" 30 | sed 's/[0-9]//g') >> $OUT
			ret_code=$2
		fi
	fi

	if [ "$ret_code" -ne 255 ] ; then
		cp -pf $full_log_name"1" $full_log_name
	fi

	return $ret_code
}

usage() {
	conv_cp "Применение: $0 [-f <имя файла настроек>]"
	exit 255
}

create_diff_ini() {
	ret_ini_code=0
	
	if [[ -f $1 ]]; then
		# разбор ini файла

		while read path access err_code time; do
			if [[ -d $path ]] ; then
				create_diff $path $access $err_code $time
				e_code=$?
				case $e_code in 
				254) 
					conv_cp "Замечены изменения в $path. Эта информация для ознакомления."
					if [ $ret_ini_code -lt 255 ] ; then
						ret_ini_code=$e_code
					fi

					;;
				255) 
					conv_cp "Произведены изменения в $path. Проконсультируйтесь с администратором."
					ret_ini_code=$e_code

					;;

				esac
			else 
				if [ -z `echo $path | egrep -o '^$|^#'` ] ; then
					conv_cp "путь \"$path\" не найден"
				fi 
			fi

		done < $1
		
	else
		conv_cp "файл настроек $1 не найден"
		ret_ini_code=255
	fi
	return $ret_ini_code
}

echo $SPLIT_LINE
conv_cp "Утилита проверки целостности программ и данных АДИС"
#------------------------------
# если несанкционированные изменения были в этом каталоге, возвращаем ошибку 255
create_diff $BIN 255
exit_code=$?
 
if [ $exit_code -ne 0 ] ; then
	conv_cp "Произведены изменения в $BIN. Проконсультируйтесь с администратором."
fi

#------------------------------
while getopts ':hf:' OPTION  
do
	case $OPTION in
	h)	
		usage;
		;; 
	f)	FILE_OPT=$OPTARG
		create_diff_ini $FILE_OPT
		temp=$?

		if [ $exit_code -lt 255 ] ; then
 			exit_code=$temp
 		fi

		;;
	*)
		usage;
		;;
	esac 
done

if [ $exit_code -eq 0 ] ; then
	conv_cp "В наблюдаемых каталогах изменений не обнаружено."
fi
echo $SPLIT_LINE

exit $exit_code
