#! /bin/sh

#
# Copyright Rainer Wichmann (2006)
#
# License Information:
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#

MAXTEST=57; export MAXTEST

run_flawfinder ()
{
    flawfinder --minlevel=3 --quiet src/s*.c | \
	egrep '^No hits found.' >/dev/null 2>&1
    if [ $? -eq 0 ]; then
	[ -z "$quiet" ] &&     log_ok   $2 ${MAXTEST} "$TEST";
    else
	flawfinder --minlevel=3 --quiet src/s*.c >test_log 2>&1
	[ -z "$quiet" ] && log_fail $2 ${MAXTEST} "$TEST";
	return 1
    fi
}

run_smatch () 
{
    export CDIR=`pwd`;

    if [ -z "$doall" ]; then
	[ -z "$quiet" ] && log_skip $2 ${MAXTEST} "$TEST (smatch)";
	return 0
    fi

    if [ "x$3" = "xdebug" ]; then memcheck=debug; else memcheck=simple; fi
    if [ -f ../sm_scripts/smatch.pm ]; then
	( 
	    cd ../sm_scripts;
	    
	    for i in ${CDIR}/*.c.sm ; do
	        # echo $i;
		cat $i | ./unreached_code.pl;
		cat $i | ./ampersand_missing.sh;
		cat $i | ./uninitialized.pl;
		cat $i | ./eqeq.pl;
		cat $i | ./for_bounds.pl;
		cat $i | ./unchecked_returns.pl;
		cat $i | ./unreached_code.pl;
		cat $i | ./uninitialized.pl;
		# from http://people.redhat.com/mstefani/wine/smatch/
		if [ -f ./while_for_check.pl ]; then
		    cat $i | ./while_for_check.pl;
		fi 
		# --> end wine <--
		# samhain specific
		if [ $memcheck = xsimple ]; then
		    if [ -f ./samhain_unfree.pl ]; then
			cat $i | ./samhain_unfree.pl | \
			    egrep -v 'x_cutest_.*Test_' | \
			    egrep -v 'x_sh_unix.c .... .... sh_unix_copyenv';
		    fi 
		fi
		if [ $memcheck = xdebug ]; then
		    if [ -f ./samhain_unfree_debug.pl ]; then
			cat $i | ./samhain_unfree_debug.pl | \
			    egrep -v 'x_cutest_.*Test_' | \
			    egrep -v 'x_sh_unix.c .... .... sh_unix_copyenv';
		    fi 
		fi
		# --> end samhain specific <--
		#cat $i | ./unfree.pl | \
		#    egrep -v 'x_cutest_.*Test_' | \
		#    grep -v 'x_sh_unix.c .... .... sh_unix_copyenv';
		touch list_null_funcs_uniq;
		cat $i | ./deference_check.pl;
		rm -f list_null_funcs_uniq;
		rm -f $i
	    done
	) >test_log_smatch 2>&1
	if [ -f test_log_smatch ]; then
	    lines=`cat test_log_smatch | wc -l`
	    if [ $lines -ne 0 ]; then
		cat test_log_smatch
		rm -f test_log_smatch
		[ -z "$quiet" ] && log_fail $2 ${MAXTEST} "$TEST (smatch)";
		return 1
	    fi
	fi
	[ -z "$quiet" ] && log_ok $2 ${MAXTEST} "$TEST (smatch)";
	return 0
    fi
    [ -z "$quiet" ] && log_skip $2 ${MAXTEST} "$TEST (smatch)";
    return 0
}

testmake ()
{
	fail=0
	if test x$1 = x0; then
		[ -z "$verbose" ]     ||  log_msg_ok  "configure...  $TEST";
		$MAKE ${SMATCH} cutest > /dev/null 2>> test_log
		if test x$? = x0; then
		    [ -z "$verbose" ] || log_msg_ok   "make cutest... $TEST";
 		else
		    [ -z "$quiet" ] &&   log_msg_fail "make cutest... $TEST";
		    fail=1
		fi
	else
		[ -z "$quiet" ] &&       log_msg_fail "configure...   $TEST";
	        if [ x"$3" = xskip ]; then
		    [ -z "$quiet" ] && log_skip $2 ${MAXTEST} "$TEST";
		fi
		fail=1
	fi
	if [ $fail -eq 1 ]; then
	    [ -z "$quiet" ] && log_fail $2 ${MAXTEST} "$TEST";
	    return 1
	fi
	[ -z "$quiet" ] &&     log_ok   $2 ${MAXTEST} "$TEST";
	return 0
}

testcompile ()
{
	log_start "COMPILE"

	if [ -f /usr/local/gcc-smatch/bin/gcc ]; then
	    SAVE_CC="${CC}"
	    SMATCH="DBGDEF=--smatch"; export SMATCH
	    CC="/usr/local/gcc-smatch/bin/gcc"; export CC
	fi

	num=0
	numfail=0

	#
	# test flawfinder
	#
        TEST="${S}check w/flawfinder${E}"
	#
	#
	let "num = num + 1" >/dev/null
	FLAWFINDER=`find_path flawfinder`
	#
	if [ -z "$FLAWFINDER" ]; then
	    log_skip $num $MAXTEST 'check w/flawfinder (not in PATH)'
	else
	    run_flawfinder 0 $num || let "numfail = numfail + 1"  >/dev/null
	fi
	#

	#
	# test standalone compilation
	#
        TEST="${S}standalone w/suidcheck${E}"
	#
	if test -r "Makefile"; then
		$MAKE distclean 
	fi
	#
	${TOP_SRCDIR}/configure --quiet  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  --enable-suidcheck > /dev/null 2>> test_log
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1"  >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation
	#
        TEST="${S}standalone w/mounts-check w/userfiles${E}"
	#
	if test -r "Makefile"; then
		$MAKE distclean 
	fi
	#
	${TOP_SRCDIR}/configure --quiet  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  --enable-mounts-check --enable-userfiles  > /dev/null 2>> test_log
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null


	#
	# test standalone compilation
	#
        TEST="${S}standalone w/timeserver and w/msgqueue${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean 
	fi
	#
	${TOP_SRCDIR}/configure --quiet  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  --enable-message-queue --with-timeserver=127.0.0.1 > /dev/null 2>> test_log
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation with --with-nocl=PW
	#
	TEST="${S}standalone w/nocl${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet  --prefix=$PW_DIR --enable-nocl="owl" --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation w/ debug
	#
	TEST="${S}standalone w/debug${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-debug  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num debug || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation w/ gpg
	#
	TEST="${S}standalone w/gpg${E}"
	#
	GPG=`find_path gpg`
	let "num = num + 1" >/dev/null
	#
	if [ -z "$GPG" ]; then
	    log_skip $num $MAXTEST 'gpg not in PATH'
            let "num = num + 1" >/dev/null
	else
	    if test -r "Makefile"; then
		$MAKE clean
	    fi
	    #
	    ${TOP_SRCDIR}/configure --quiet --with-gpg=$GPG  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	    #
	    testmake $? $num || let "numfail = numfail + 1" >/dev/null
	    let "num = num + 1" >/dev/null
	    run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	fi

	#
	# test standalone compilation w/stealth
	#
	TEST="${S}standalone w/stealth${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-stealth=128 --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation w/logwatch
	#
	TEST="${S}standalone w/login-watch${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-login-watch  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation w/mysql
	#
	TEST="${S}standalone w/mysql${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-xml-log --with-database=mysql  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log
	#
	let "num = num + 1" >/dev/null
	testmake $? $num "skip" || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation w/postgresql
	#
	TEST="${S}standalone w/postgresql${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-xml-log --with-database=postgresql  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log
	#
	let "num = num + 1" >/dev/null
	testmake $? $num "skip" || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation
	#
	TEST="${S}standalone w/o mail${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --disable-mail --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test standalone compilation
	#
	TEST="${S}standalone w/o external${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --disable-external-scripts --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	# echo; echo "${S}__ TEST CLIENT/SERVER __${E}"; echo;

	#
	# test client/server compilation
	#
	TEST="${S}client/server application w/timeserver${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client  --enable-srp --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test   --with-timeserver=127.0.0.1 > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server  --enable-srp --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test   --with-timeserver=127.0.0.1 > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test c/s compilation w/ gpg
	#
	TEST="${S}client/server application w/gpg${E}"
	#
	GPG=`find_path gpg`
	let "num = num + 1" >/dev/null
	#
	if [ -z "$GPG" ]; then
	    log_skip $num $MAXTEST 'gpg not in PATH'
	    let "num = num + 3" >/dev/null
	else
	    if test -r "Makefile"; then
		$MAKE clean
	    fi
	    #
	    ${TOP_SRCDIR}/configure --quiet --enable-network=server  --enable-srp --with-gpg=$GPG  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	    #
	    testmake $? $num || let "numfail = numfail + 1" >/dev/null
	    let "num = num + 1" >/dev/null
	    run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	    #
	    if test -r "Makefile"; then
		$MAKE clean
	    fi
	    #
	    ${TOP_SRCDIR}/configure --quiet --enable-network=client  --enable-srp --with-gpg=$GPG  --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	    #
	    let "num = num + 1" >/dev/null
	    testmake $? $num || let "numfail = numfail + 1" >/dev/null
	    let "num = num + 1" >/dev/null
	    run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	fi


	#
	# test client/server compilation
	#
	TEST="${S}client/server application w/o srp${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server --disable-srp --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client --disable-srp --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test client/server compilation w/ debug
	#
	TEST="${S}client/server application w/debug${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server --enable-debug --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num debug || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client --enable-debug --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num debug || let "numfail = numfail + 1"  >/dev/null

	#
	# test client/server compilation w/stealth
	#
	TEST="${S}client/server application w/stealth${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server  --enable-srp --enable-stealth=128 --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client  --enable-srp --enable-stealth=128 --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test  client/server compilation w/logwatch
	#
	TEST="${S}client/server application w/login-watch${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server  --enable-srp --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client  --enable-srp --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test  > /dev/null 2>> test_log  
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	#
	# test client/server compilation
	#
	TEST="${S}client/server application w/o mail${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server  --disable-mail --enable-srp --enable-stealth=128 --enable-debug --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num debug || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client  --disable-mail --enable-srp --enable-stealth=128 --enable-debug --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num debug || let "numfail = numfail + 1"  >/dev/null

	#
	# test client/server compilation
	#
	TEST="${S}client/server application w/o external${E}"
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=server  --disable-srp --disable-external-scripts --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null
	#
	if test -r "Makefile"; then
		$MAKE clean
	fi
	#
	${TOP_SRCDIR}/configure --quiet --enable-network=client  --disable-srp --disable-external-scripts --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$PW_DIR/samhainrc.test > /dev/null 2>> test_log   
	#
	let "num = num + 1" >/dev/null
	testmake $? $num || let "numfail = numfail + 1" >/dev/null
	let "num = num + 1" >/dev/null
	run_smatch $? $num || let "numfail = numfail + 1"  >/dev/null

	[ -z "${SMATCH}" ] || { CC="${SAVE_CC}"; export CC; }

	log_end "COMPILE"
}
