#! /bin/bash

TMP_DIR=/tmp
DOC_DIR=/usr/share/doc
NEW_ROOT="/var/local/vbootstrap/5.1_i386"

IGNORE_DOC="N"
IGNORE_ERR="N"
VER_MODE="N"
VBUILDER_MODE="N"
SHOW_HELP="N"

SIG_OK="Y"
VEN_OK="Y"
LOG_UPDATE="Y"

for name in $@  ; do
    if [ $name = "-d" ]; then
	IGNORE_DOC="Y"
	continue
    fi
    if [ $name = "-i" ]; then
	IGNORE_ERR="Y"
	continue
    fi
    if [ $name = "-v" ]; then
	VER_MODE="Y"
	continue
    fi
    if [ $name = "-b" ]; then
	VBUILDER_MODE="Y"
	continue
    fi
    if [ $name = "-h" ]; then
	SHOW_HELP="Y"
	continue
    fi
done

tmp1=`echo $@|sed -e "s/ -. / /g"`
tmp2=`echo $tmp1|sed -e "s/^-. //g"`
argfile=`echo $tmp2|sed -e "s/ -.$//g"`

if [ $SHOW_HELP = "Y" ]; then
    echo " "
    echo "chkpkgv.sh [options] rpmpackage(s) "
    echo " "
    echo "  -h  ヘルプを表示します "
    echo "  -v  詳細な出力を表示します "
    echo "  -d  収録ファイルの比較のとき、/usr/share/doc の内容の違いを無視します"
    echo "  -i  Signature チェック、Vendor Tag チェックでエラーが検出されても "
    echo "      処理を続行します"
    echo "  -b  vbootstrap モードで実行します"
    echo " "
    echo "VBOOTSTRAP ROOT ="$NEW_ROOT
    echo " "
    exit
fi

echo ""
echo "Signature check"
for name in $argfile  ; do
    PKG_NAME=$name
    case $name in
        *.rpm)
            rpm -K $name | cut -f2 -d":" |grep gpg > /dev/null
            if [ $? = 0 ]; then
		rpm -K $name |grep "NOT OK"
		if [ $? = 0 ]; then
		    echo -e "---- \033[1;31mFAIL\033[0m : "`basename $name`
		    SIG_OK="N"
		else
		    echo -e "\033[1;32mPass\033[0m ---- : "`basename $name`
		fi
	    else
		echo -e "---- \033[1;31mFAIL\033[0m : "`basename $name`
		SIG_OK="N"
	    fi
            ;;
        *)
            echo $name" is NOT rpm package (skipped)"
            continue
            ;;
    esac
done

echo ""
echo "Vendor check"
for name in $argfile  ; do
    PKG_NAME=$name
    case $name in
        *.rpm)
            rpm -qip $name |grep "Vendor:"|grep "(none)"
            if [ $? = 0 ]; then
                echo -e "---- \033[1;31mFAIL\033[0m : "`basename $name`
		VEN_OK="N"
	    else
		echo -e "\033[1;32mPass\033[0m ---- : "`basename $name`
            fi
            ;;
        *)
            echo $name" is NOT rpm package (skipped)"
            continue
            ;;
    esac
done

if [ $VBUILDER_MODE = "Y" ]; then
    RPM_CMD="rpm --root="$NEW_ROOT
    APTC_CMD="sudo chroot "$NEW_ROOT" apt-cache "
    APTG_CMD="sudo chroot "$NEW_ROOT" apt-get "
    ARV_DIR=$NEW_ROOT/var/cache/apt/archives
    echo ""
    echo "vbootstrap mode"
    echo "New root = "$NEW_ROOT
else
    RPM_CMD=rpm
    APTC_CMD=apt-cache
    APTG_CMD="sudo apt-get "
    ARV_DIR=/var/cache/apt/archives
fi

# echo $NEW_ROOT
# echo $RPM_CMD
# echo $APTC_CMD
# echo $APTG_CMD

echo ""
echo "Changelog Check"
for name in $argfile  ; do
    PKG_NAME=$name
    case $name in
        *.rpm)
	    TMP=`$RPM_CMD -qip $PKG_NAME|grep ^Name|cut -f2 -d:`
	    PKG_BASE_NAME=`echo $TMP|cut -f1 -d" "`
	    
	    LANG=C $RPM_CMD -q --changelog $PKG_BASE_NAME > $TMP_DIR/installed_pkg
	    grep -q "$PKG_BASE_NAME is not installed" $TMP_DIR/installed_pkg
	    if [ $? = 0 ]; then
		echo $PKG_BASE_NAME" is not installed (getting from apt repository)"
		$APTC_CMD --no-all-versions -q show $PKG_BASE_NAME > $TMP_DIR/current_pkg
		if [ $? -gt 0 ]; then
		    echo $PKG_BASE_NAME" is not found in apt repository (skipped)"
		    continue
		fi
		
		APT_PKG=`cat $TMP_DIR/current_pkg|grep "^Package:"|cut -f2 -d" "`
		APT_VER=`cat $TMP_DIR/current_pkg|grep "^Version:"|cut -f2 -d" "|sed "s/.://"`
		APT_ARCH=`cat $TMP_DIR/current_pkg|grep "^Architecture:"|cut -f2 -d" "`
		APT_ARV_FILE=$ARV_DIR"/"$APT_PKG"-"$APT_VER"."$APT_ARCH.rpm

		if [ -f $APT_ARV_FILE ]; then
		    echo $APT_ARV_FILE" is found."
		else
		    $APTG_CMD -d -qq install $APT_PKG
		fi
		LANG=C $RPM_CMD -qp --changelog $APT_ARV_FILE > $TMP_DIR/installed_pkg
	    fi

	    LANG=C $RPM_CMD -qp --changelog $PKG_NAME > $TMP_DIR/new_pkg

	    diff -q $TMP_DIR/installed_pkg $TMP_DIR/new_pkg > /dev/null
	    if [ $? = 0 ]; then
		echo -e "---- \033[1;31mFAIL\033[0m : "`basename $PKG_NAME`
		LOG_UPDATE="N"
	    else

		TLD_INSED=`head -n1 $TMP_DIR/installed_pkg|sed s/\*\ //|cut -d" " -f1,2,3,4` 
		TLD_NEW=`head -n1 $TMP_DIR/new_pkg|sed s/\*\ //|cut -d" " -f1,2,3,4`
		if [ "$TLD_INSED" = "$TLD_NEW" ]; then
		    echo "*************************************"
		    echo "*            WARNING !!             *"
		    echo "* Change log DATE is NOT updated !! *"
		    echo "*************************************"
		fi
#		echo `basename $PKG_NAME`
		echo -e "\033[1;32mPass\033[0m ---- : "`basename $PKG_NAME`
		diff $TMP_DIR/installed_pkg $TMP_DIR/new_pkg > $TMP_DIR/diff_changelog_next
		if [ -f $TMP_DIR/diff_changelog ]; then
		    diff -q $TMP_DIR/diff_changelog $TMP_DIR/diff_changelog_next > /dev/null
		    if [ $? -ne 0 ]; then
			DIFF_LINE=`cat $TMP_DIR/diff_changelog_next|wc -l`
			if [ $DIFF_LINE -lt "20" ]; then
			    cat $TMP_DIR/diff_changelog_next
			else
			    cat $TMP_DIR/diff_changelog_next|head -n10
			    echo "Changelog diff is too long.. skipped."
			fi
		    fi
		else
		    DIFF_LINE=`cat $TMP_DIR/diff_changelog_next|wc -l`
#		    echo $DIFF_LINE
		    if [ $DIFF_LINE -lt "20" ]; then
			cat $TMP_DIR/diff_changelog_next
		    else
			cat $TMP_DIR/diff_changelog_next|head -n10
			echo "Changelog diff is too long.. skipped."
		    fi
		    mv $TMP_DIR/diff_changelog_next $TMP_DIR/diff_changelog
		fi
	    fi
            ;;
        *)
            echo $name" is NOT rpm package (skipped)"
            continue
            ;;
    esac
done

rm -rf $TMP_DIR/diff_changelog_next $TMP_DIR/diff_changelog

echo ""
if [ $IGNORE_ERR = "N" ]; then
    if [ $SIG_OK = "N" ]; then
	exit
    fi
    if [ $VEN_OK = "N" ]; then
	exit
    fi
    if [ $LOG_UPDATE = "N" ]; then
	exit
    fi
fi

if [ $IGNORE_DOC = "Y" ]; then
    echo "Files check (Ignore Document Mode)"
else
    echo "Files check"
fi
for name in $argfile  ; do

    PKG_NAME=$name
    echo $PKG_NAME|grep -q ".src.rpm"
    if [ $? = 0 ]; then
	echo "Skip ---- : "`basename $PKG_NAME`" (src package)"
	continue
    fi

    TMP=`$RPM_CMD -qip $PKG_NAME|grep ^Name|cut -f2 -d:`
    PKG_BASE_NAME=`echo $TMP|cut -f1 -d" "`

    LANG=C $RPM_CMD -ql $PKG_BASE_NAME > $TMP_DIR/installed_pkg
    grep -q "$PKG_BASE_NAME is not installed" $TMP_DIR/installed_pkg
    if [ $? = 0 ]; then
	echo $PKG_BASE_NAME" is not installed (getting from apt repository)"
	$APTC_CMD --no-all-versions -q show $PKG_BASE_NAME > $TMP_DIR/current_pkg
	if [ $? -gt 0 ]; then
	    echo $PKG_BASE_NAME" is not found in apt repository (skipped)"
	    continue
	fi
	
	APT_PKG=`cat $TMP_DIR/current_pkg|grep "^Package:"|cut -f2 -d" "`
	APT_VER=`cat $TMP_DIR/current_pkg|grep "^Version:"|cut -f2 -d" "|sed "s/.://"`
	APT_ARCH=`cat $TMP_DIR/current_pkg|grep "^Architecture:"|cut -f2 -d" "`
	APT_ARV_FILE=$ARV_DIR"/"$APT_PKG"-"$APT_VER"."$APT_ARCH.rpm

	if [ -f $APT_ARV_FILE ]; then
	    echo $APT_ARV_FILE" is found."
	else
	    $APTG_CMD -d -qq install $APT_PKG
	fi
	LANG=C $RPM_CMD -qlp $APT_ARV_FILE > $TMP_DIR/installed_pkg
    fi

    LANG=C rpm -qlp $PKG_NAME > $TMP_DIR/new_pkg

    if [ $IGNORE_DOC = "Y" ]; then
	rm -f $TMP_DIR/tmp_pkg
	grep -v $DOC_DIR/$PKG_BASE_NAME $TMP_DIR/new_pkg > $TMP_DIR/tmp_pkg 
	mv $TMP_DIR/tmp_pkg $TMP_DIR/new_pkg
	grep -v $DOC_DIR/$PKG_BASE_NAME $TMP_DIR/installed_pkg > $TMP_DIR/tmp_pkg 
	mv $TMP_DIR/tmp_pkg $TMP_DIR/installed_pkg
    fi

    diff -q $TMP_DIR/installed_pkg $TMP_DIR/new_pkg
    if [ $? = 0 ]; then
	echo -e "\033[1;32mPass\033[0m ---- : "$PKG_BASE_NAME
    else
	echo -e "---- \033[1;31mFAIL\033[0m : "$PKG_BASE_NAME
	if [ $VER_MODE = "Y" ]; then
	    diff $TMP_DIR/installed_pkg $TMP_DIR/new_pkg
	else
	    INSTALLED_BYTE=`wc -c $TMP_DIR/installed_pkg|cut -f1 -d" "`
	    INSTALLED_WORD=`wc -w $TMP_DIR/installed_pkg|cut -f1 -d" "`
	    INSTALLED_LINE=`wc -l $TMP_DIR/installed_pkg|cut -f1 -d" "`
	    NEW_BYTE=`wc -c $TMP_DIR/new_pkg|cut -f1 -d" "`
	    NEW_WORD=`wc -w $TMP_DIR/new_pkg|cut -f1 -d" "`
	    NEW_LINE=`wc -l $TMP_DIR/new_pkg|cut -f1 -d" "`
	    echo "Installed : "$INSTALLED_BYTE $INSTALLED_WORD $INSTALLED_LINE $PKG_BASE_NAME
	    echo "New       : "$NEW_BYTE $NEW_WORD $NEW_LINE `basename $PKG_NAME`
	fi
    fi
done

echo ""
echo "Requires check"
for name in $argfile  ; do

    PKG_NAME=$name
    echo $PKG_NAME|grep -q ".src.rpm"
    if [ $? = 0 ]; then
	echo "Skip ---- : "`basename $PKG_NAME`" (src package)"
	continue
    fi

    TMP=`rpm -qip $PKG_NAME|grep ^Name|cut -f2 -d:`
    PKG_BASE_NAME=`echo $TMP|cut -f1 -d" "`

    LANG=C rpm -qRp $PKG_NAME |sort|uniq > $TMP_DIR/new_pkg
    LANG=C $RPM_CMD -qR $PKG_BASE_NAME |sort|uniq > $TMP_DIR/installed_pkg
    grep -q "$PKG_BASE_NAME is not installed" $TMP_DIR/installed_pkg
    if [ $? = 0 ]; then
	echo $PKG_BASE_NAME" is not installed (getting from apt repository)"

	$APTC_CMD --no-all-versions -q show $PKG_BASE_NAME > $TMP_DIR/current_pkg
	if [ $? -gt 0 ]; then
	    echo $PKG_BASE_NAME" is not found in apt repository (skipped)"
	    continue
	fi
	
	APT_PKG=`cat $TMP_DIR/current_pkg|grep "^Package:"|cut -f2 -d" "`
	APT_VER=`cat $TMP_DIR/current_pkg|grep "^Version:"|cut -f2 -d" "|sed "s/.://"`
	APT_ARCH=`cat $TMP_DIR/current_pkg|grep "^Architecture:"|cut -f2 -d" "`
	APT_ARV_FILE=$ARV_DIR"/"$APT_PKG"-"$APT_VER"."$APT_ARCH.rpm

	if [ -f $APT_ARV_FILE ]; then
	    echo $APT_ARV_FILE" is found."
	else
	    $APTG_CMD -d -qq install $APT_PKG
	fi
	LANG=C $RPM_CMD -qRp $APT_ARV_FILE |sort|uniq > $TMP_DIR/installed_pkg
    fi

    diff -q $TMP_DIR/installed_pkg $TMP_DIR/new_pkg > /dev/null
    if [ $? = 0 ]; then
	echo -e "\033[1;32mPass\033[0m ---- : "$PKG_BASE_NAME
    else
	echo -e "---- \033[1;31mFAIL\033[0m : "$PKG_BASE_NAME
	diff $TMP_DIR/installed_pkg $TMP_DIR/new_pkg
    fi
done


echo ""
echo "Plus Requires check"
for name in $argfile  ; do

    PKG_NAME=$name
    PKG_BASE_NAME=`basename $PKG_NAME`
    PLUS_OK="Y"

    echo $PKG_NAME|grep -q ".src.rpm"
    if [ $? = 0 ]; then
	echo "Skip ---- : "`basename $PKG_NAME`" (src package)"
	continue
    fi
    LIBLIST=`LANG=C rpm -qRp $PKG_NAME |cut -f1 -d" "|cut -f1 -d"("|sort|uniq`

    for LIB in $LIBLIST ; do
	echo $LIB | grep -q "\(/bin\)\|\(/sbin\)\|\(rpmlib\)"
	if [ $? = 0 ]; then
	    if [ $VER_MODE = "Y" ]; then
		echo "Skip ....... "$LIB
	    fi
	    continue
	fi
	if [ $VER_MODE = "Y" ]; then
	    echo "Checking ... "$LIB
	fi

	echo $LIB | grep -q "\.so\."
	if [ $? = 0 ]; then
	    # so lib
	    PNAME=`$APTC_CMD --names-only search $LIB|cut -f1 -d" "|sed s/gtk210.*//`
	    $APTC_CMD --no-all-versions showpkg $PNAME|grep -q "pkglist\.plus"
	    if [ $? = 0 ]; then
		echo "VinePlus "$PNAME"("$LIB") is required" 
		PLUS_OK="N"
	    fi
	else
	    # package
	    PNAME=$LIB
	    $APTC_CMD --no-all-versions showpkg $PNAME|grep -q "pkglist\.plus"
	    if [ $? = 0 ]; then
		echo "VinePlus "$PNAME" is required" 
		PLUS_OK="N"
	    fi
	fi
    done

    if [ $PLUS_OK = "Y" ]; then
	echo -e "\033[1;32mPass\033[0m ---- : "$PKG_BASE_NAME
    else
	echo -e "---- \033[1;31mFAIL\033[0m : "$PKG_BASE_NAME
    fi
done
