#!/bin/sh
#
#builddb: version 1.0
#
#the script performs a search of dependencies using ldd and after scans the /var/log/packages directory
#searching for the tgz's related to the dependencies of a file.
#the result is a log file with the list of the whole tgz's related to the ELF files contained into the passed tgz.
#
#usage:
#
#./builddb packagename
#
#where:
#pkgname is the name of the tgz package inside the slack database.
#
#to do:
#
#-optimize elf search!
#-add a log file for the "not-full-path" searching mode...???
#-we need a better optimization (again :)



#--------------------------------------------------------------
#aux. functions - useful stuff for the tracing of dependencies

. $INSTDIR/core-functions

#--------------------------------------------------------------


#--------------------------------------------------------------
#main body


	PACKAGE=$1

	echo ""
	echo $PACKAGE
	BASENAME_=`basename $PACKAGE .tgz`;
	NAME=$PKGDIR/$BASENAME_	#useful???

	#get tgz's binary file list
	echo "getting ELF file list for $BASENAME_"

	FILELIST[0]=""

	grabException $BASENAME_
	[ $? -eq 0 ] && fillFileArray $NAME

	[ "${FILELIST[0]}" = "" ] && {
		echo "Neither dynamically linked executables nor shared objects found in common locations (/.../{bin/,sbin/,lib/})";
		exit 1;
	}

	#get the dependency list for all binaries
	#we sort results removing common dependencies:
	echo "getting dependency list for all ELF files"

	#get installed dependencies
	DEPLIST=(`echo ${FILELIST[@]} | xargs ldd 2>/dev/null | grep -vi "not found\|dynamic\|statically\|:$" | awk -F '=>' '{printf $NF"\n"}' \
	| sed -e 's/^	//;s/^ //;s/\(0x\w.......\)//' | cut -f1 -d \ | sort | uniq`);

	#get missing dependencies
	#
	#	this includes also false negatives, that is, dependencies installed in paths not listed
	#	inside the ld.so.conf file -which is used by ldd to detect installed lib's-
	#
	MISLIST=(`echo ${FILELIST[@]} | xargs ldd 2>/dev/null | grep -i "not found" | cut -f1 -d \ | cut -b 2- | sort | uniq`)

	#define log file name for missing dependencies
	MISFILE="$MISDIR/$BASENAME_"

	#remove old log file if found
	[ -f $MISFILE ] && rm $MISFILE

	#if we have some missing dep's we store them
	[ ! ${#MISLIST[@]} -eq 0 ] && {

		#
		#	the following solution to remove false negatives is not the most elegant
		#	but is the fastest I've found!
		#
		#check false negatives inside the given package (the most probable place)
		FALSEMIS=(`grep -wo -F "$(echo ${MISLIST[@]} | sed -e 's/ /\n/g')" $1`)

		[ ! ${#FALSEMIS[@]} -eq 0 ] && {
		#remove false negatives if found
			[ ${#FALSEMIS[@]} -eq ${#MISLIST[@]} ] || {
			#update missing dependencies list: if all missing dependencies are
			#false negatives we delete the $MISFILE else we overwrite it with
			#all and only _REAL_ missing dependencies
				for (( i=0; i<${#MISLIST[@]}; i++ )); do
					for (( j=0; j<${#FALSEMIS[@]}; j++ )); do
						[ "${MISLIST[$i]}" = "${FALSEMIS[$j]}" ] && MISLIST[$i]=""
					done
				done
				echo ${MISLIST[@]} | sed -e 's/ /\n/g' > $MISFILE
			}
		} || { #if we have not false negatives
			echo ${MISLIST[@]} | sed -e 's/ /\n/g' > $MISFILE
		}
	}

	#define log file name for installed dependencies
	DEPFILE="$LOGDIR/$BASENAME_"

	#remove old log file if found
	[ -f $DEPFILE ] && rm $DEPFILE

	if [ ${#DEPLIST[@]} -eq 0 ]; then
	#if we haven't found any installed dependency...
		echo "No installed dependencies found for $PACKAGE";
	else
		echo "searching related tgz's"

		#search related tgz's
		TDEPFILES=""
		for (( i=0; i<${#DEPLIST[@]}; i++ )); do
			searchDep ${DEPLIST[$i]} $NAME "-wlm 1"
		done

		echo "cleaning results"
		echo

		if [ ! "$TDEPFILES" = "" ]; then
			#clean log file removing repeated names
			echo $TDEPFILES | sed -e 's/ /\n/g;' | sort | uniq | \
			sed -e "/openssl-[0-9]/d;/glibc-[0-9]/d;" > $DEPFILE

			if [ ! -f $MISFILE ]; then
				echo -e "  --> Installed dependency list stored in:\n      $DEPFILE"
			else
				echo -e "  --> Installed dependency list stored in:\n      $DEPFILE"
				echo -e "  --> Missing dependency list stored in:\n      $MISFILE"
				echo -e "\n  --> the following libs/files are required by $BASENAME_ and are missing:"
				cat $MISFILE
			fi
		else
			#if we haven't dependencies we remove everything.
			#NB: a lack of dependencies here is equal to a mistake...
			echo "* tracing failed:"
			echo "* unable to find dependencies into installed tgz's"
		fi
	fi

	echo ""


#---------------------------------------------------

#EOF