#!/bin/sh

modulename=weasel
dir=/proc/$modulename

if ! modprobe $modulename; then
	echo "Could not load module $modulename.ko!"
	exit 1
fi

if ! [ -d "$dir" ]; then
	echo "$dir not created!"
	exit 1
fi


if ! [ -f "$dir/whoami" ]; then
	ls -l "$dir"
	echo "$dir/whoami not created!"
	exit 1
fi

who=$(cat "$dir/whoami")

if [ -z "$who" ] || ! printf "%s" "$who" | grep -qi "I'm a weasel"; then
	echo "Wrong string in whoami!"
	exit 1
fi

if ! [ -f "$dir/info" ]; then
	ls -l "$dir"
	echo "$dir/info not created!"
	exit 1
fi

info=$(cat "$dir/info")
# we are checking that the right values are printed against a valid solution
#info_solution=$(cat "${dir}_solution/info")

echo "$info"

compare() {
	if [ -z "$1" ] || [ -z "$2" ] || [ "$1" != "$2" ]; then
		return 1
	fi
	return 0
}

# we are checking that the right values are printed against a valid solution
address=$(printf '%s' "$info" | grep -oP 'address:\s*\K0x[^\s]+' )
#address_solution=$(printf '%s' "$info_solution" | grep -oP 'address:\s*\K0x[^\s]+')

# we are checking that the right values are printed against a valid solution
size=$(printf '%s' "$info" | grep -oP 'size:\s*\K[^\d]+' )
#size_solution=$(printf '%s' "$info_solution" | grep -oP 'size:\s*\K[^\d]+')

# we are checking that the right values are printed against a valid solution
entries=$(printf '%s' "$info" | grep -oP 'entries:\s*\K[^\d]+' )
#entries_solution=$(printf '%s' "$info_solution" | grep -oP 'entries:\s*\K[^\d]+')

# we are checking that the right values are printed against a valid solution
longest=$(printf '%s' "$info" | grep -oP 'longest:\s*\K[^\d]+' )
#longest_solution=$(printf '%s' "$info_solution" | grep -oP 'longest:\s*\K[^\d]+')

#if ! compare "$address" "$address_solution"; then
#	echo "Address field is wrong!"
#	exit 1
#fi
#
#if ! compare "$size" "$size_solution"; then
#	echo "size field is wrong!"
#	exit 1
#fi
#
#if ! compare "$entries" "$entries_solution"; then
#	echo "entries field is wrong!"
#	exit 1
#fi
#
#if ! compare "$longest" "$longest_solution"; then
#	echo "longest field is wrong!"
#	exit 1
#fi


if ! [ -f "$dir/dcache" ]; then
	ls -l "$dir"
	echo "$dir/dcache not created!"
	exit 1
fi

if ! cat "$dir/dcache" >/dev/null; then
	echo "error while reading $dir/dcache"
fi

lines=$(wc -l < "$dir/dcache")
# we are checking that the right values are printed against a valid solution
# lines_solution=$(wc -l < "${dir}_solution/dcache")
lines=$(wc -l < "$dir/dcache")

# if [ -z "$lines" ] || ! [ "$lines" -eq "$lines_solution" ]; then
# 	echo "incorrect number of lines in $dir/dcache: should be $lines_solution instead of $lines"
# 	exit 1
# fi

timeout 1s find / -type f >/dev/null 2>&1

lines=$(wc -l < "$dir/dcache")
# we are checking that the right values are printed against a valid solution
#lines_solution=$(wc -l < "${dir}_solution/dcache")

if [ -z "$lines" ] || ! [ "$lines" -eq "$lines_solution" ]; then
	echo "incorrect number of lines in $dir/dcache: should be $lines_solution instead of $lines"
	exit 1
fi

if ! [ -f "$dir/pwd" ]; then
	ls -l "$dir"
	echo "$dir/pwd not created!"
	exit 1
fi

if ! cat "$dir/pwd" >/dev/null; then
	echo "error while reading $dir/pwd"
fi

# running a command that doesn't exist to check the creation of entries in /proc/weasel/pwd
command_that_doesnt_exist 2>/dev/null

if ! grep -q "command_that_doesnt_exist" "$dir/pwd"; then
	echo "can't find command in $dir/pwd"
	exit 1
fi

# generate a couple of random command and then, check if 
# the correct number of entries are created in the dentry cache
random_str=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 12)
for _ in $(seq "$(od -An -N1 -i /dev/urandom | tr -d ' ')"); do
	$random_str 2>/dev/null

	if ! grep -q "$random_str" "$dir/pwd"; then
		echo "can't find command in $dir/pwd"
		exit 1
	fi

done

if ! rmmod $modulename; then
	echo "Fail while unloading module"
	exit 1
fi

echo scan > /sys/kernel/debug/kmemleak
sleep 60
cat /sys/kernel/debug/kmemleak
