#!/bin/sh
#
# author: hackbard@hackdaworld.dyndns.org
#
# hdw-tools: 
# this is hdw-get script, used to install/remove/(update) binary packages
# 

usage()	{
	echo
	echo "usage:"
	echo "$0 [install/remove] [root] [package]"
	echo "$0 [dist-install] [root] [dist file]"
	echo "$0 [update]"
	echo
	echo "options:"
	echo "-v	tell me whats going on"
	echo "-a	auto resolve deps, do not prompt user"
	echo "-no-dep	do not care for dependencies (used by hdw-get itself)"
	echo "-s	simulation only, do not install/remove packages"
	echo "-b	base package, not listed in hdw-get.db"
	echo
}

package="" ; inst_root=""
update=""
d_install="" ; install=""
verbose="" ; no_dep=""
auto_resolve_deps=""
simulate=""
base=""
answer="y"

FL_DIR="var/adm/flists"
DEPS_DIR="var/adm/deps/run"
CONF="/etc/hdw-get.conf"
DBF="/etc/hdw-get.db"

while [ "$1" ] ; do
	case "$1" in
		update)		update="1" ; package="fake" ; inst_root="fake"
				shift 1 ;;
		install)	install="1" 
				inst_root="$2" ; package="$3" ; shift 3 ;;
		remove)		remove="1" 
				inst_root="$2" ; package="$3" ; shift 3 ;;
		dist-install)	d_install="1"  ; package="fake"
				inst_root="$2" ; dist_file="$3" ; shift 3 ;;
		-v)		verbose=1 ; shift 1 ;;
		-a)		auto_resolve_deps="1" ; shift 1 ;;
		-no-dep)	no_dep="1" ; shift 1 ;;
		-s)		simulate="1" ; shift 1 ;;
		-b)		base="1" ; no_dep="1" ; shift 1;;
		*)		usage ; exit 1 ;;
	esac
done
			
if [ -z "inst_root" -o -z "$package" ] ; then
	usage ; exit 1
fi
	
# read hdw-get configs
net_addr="" ; bin_dir="" ; distf_dir=""
if [ -f $CONF ] ; then
	. $CONF
	if [ -z "$hdw_version" -o -z "$hdw_arch" -o -z "$hdw_arch_opt" ] ; then
		echo "version, arch and arch_opt need to be specified."
		echo "adjust $CONF file"
		exit
	else
		[ "$verbose" ] && echo "hdw-get.conf file looks good ..."
	fi
else
	echo "$CONF file not found, aborting"
	exit 1
fi

if [ "$update" = "1" ] ; then
	echo -en "updating hdw-get.db file ..."
	wget -q $net_addr/hdw-linux/hdw-linux-$hdw_version/hdw-get/hdw-get.db \
		-O $DBF
	echo -en " done. (`cat $DBF | wc -l` packages)\n"
fi

# remove
if [ "$remove" = "1" ] ; then
	# check if packages depend on package to be removed
	pkgs=""
	((isdep = 0))
	for fl_file in $inst_root/$DEPS_DIR/*; do
		if [ "`grep "^$package$" $fl_file`" != "" ] ; then
			pkg=`echo $fl_file | sed "s%$inst_root/$DEPS_DIR/%%"`
			if [ "$pkg" != "$package" ] ; then
				((isdep += 1))
				pkgs="$pkg $pkgs"
			fi
		fi
	done
	if [ "$isdep" != "0" ] ; then
		echo "info:"
		echo "run time dependencies were autegenerated by build system."
		echo "they may be wrong. edit $inst_root/$DEPS_DIR/* files."
		echo "deps:"
		echo -en "$pkgs\n"
		echo "package $package should not be removed ($isdep deps)"
		[ "$no_dep" != "1" ] && exit 1
	fi
	# looking for flist file
	fl_pris="unknown"
	for fl_file in $inst_root/$FL_DIR/$package-[x,0-9]*; do
		[ -f $fl_file ] && \
		fl_pris="`echo $fl_file | awk -F- '{ print $NF }'` $fl_pris"
	done
	fl_max="0"
	for pri in $fl_pris; do
		if [ "$pri" = "x" ] ; then
			fl_max="x"
			break
		fi
		[ "$pri" = "unknown" ] && break
		[ "$pri" -gt "$fl_max" ] && fl_max=$pri
	done
	fl_file="$inst_root/$FL_DIR/$package-$fl_max"
	[ "$verbose" ] && echo "expecting flist file $fl_file"
	if [ ! -f $fl_file ] ; then
		echo "package $package is not installed (moved the flist file?)"
		exit 1
	fi

	if [ "$simulate" != "1" ] ; then

	# remove the files/dirs
	#((supposed = 0))
	#((counter = 0))
	cat $fl_file | while read pkg file; do
		#((supposed += 1))
		if [ -e $inst_root/$file ] ; then
			if [ "$file" != "tmp" ] ; then
			if [ -d $inst_root/$file ] ; then
				rmdir -p $inst_root/$file > /dev/null 2>&1
			else
				rm -f $inst_root/$file > /dev/null 2>&1
				rmdir -p `dirname $file` > /dev/null 2>&1
			fi
			#((counter += 1))
			fi
		fi
		#echo -en "\rremoved $counter from $supposed supposed files"
	done
	echo -en "\ndone.\n"

	# care about info/dir file
	echo "recreating info dir file ..."
	cd $inst_root/usr/share/info
	rm -f dir
	for f in *; do
		install-info $f dir 2>/dev/null
	done

	fi

# install
elif [ "$install" = "1" ] ; then
	# does inst_root exist
	if [ ! -d $inst_root ] ; then
		echo
		echo "the install directory doesnt exist, create it first"
		echo
		exit 1
	fi

	# does package exist?
	pkg=`basename $package | sed 's/.tar.bz2//'`
	if [ -f $inst_root/$FL_DIR/${pkg}-[0-9]* ] ; then
		echo "$pkg seems to be installed, candidates:"
		for i in $inst_root/$FL_DIR/${pkg}-[0-9]*; do
			echo "-> $i"
		done
		exit 1
	fi

	# package in database?
	if [ -z $base ] ; then
		if [ "`grep "^$pkg\ -" $DBF`" = "" ] ; then
			echo "sorry, package $package not found ..."
			echo "(use 'hdw-get update' to update database)"
			exit 1
		fi
	fi

	# check for runtime deps
	if [ -z $no_dep ] ; then
		deps="`grep "^$pkg\ -" $DBF | sed 's/.* -//'`"
		udeps=""
		tudeps=""
		for dep in $deps; do
			[ "$dep" != "$pkg" ] &&
				[ ! -f $inst_root/$FL_DIR/$dep-[0-9]* ] && \
					udeps="$dep $udeps"
		done
		while [ "$udeps" != "$tudeps" ] ; do
			tudeps="$udeps"
			for tdep in $tudeps; do
				deps="`grep "^$tdep\ -" $DBF | sed 's/.* -//'`"
				for dep in $deps; do
					exists=0
					[ "$dep" = "$pkg" ] && break
					[ -f $inst_root/$FL_DIR/$dep-* ] && \
						break
					for i in $udeps; do
						[ "$i" = "$dep" ] && exists=1
					done
					[ "$exists" = "0" ] && \
						udeps="$udeps $dep"
				done
			done
		done
		if [ ".$udeps" != "." ] ; then
			echo "$pkg uninstalled depends:"
			echo "$udeps"
			echo
			echo "continue? [y,n] (default 'n')"
			answer="n"
			if [ "$auto_resolve_deps" != "1" ] ; then
				read answer
				if [ "$answer" = "y" ] ; then
					for i in $udeps; do
						[ "$simulate" != "1" ] && \
						$0 -no-dep install $inst_root $i
					done
				fi
			fi
		fi
	fi
	
	if [ "$simulate" != "1" -a "$answer" = "y" ] ; then
	
	# check/install package
	if [ -f $package ] ; then
		echo "extracting `basename $package` to $inst_root ..."
		tar --use-compress-program=bzip2 -xf $package \
			-C $inst_root
		echo "done"
	elif [ ! -z "$bin_dir" -a -f $bin_dir/${hdw_arch}-${hdw_arch_opt}/$package/$package.tar.bz2 ] ; then
		echo "extracting $package to $inst_root ..."
		tar --use-compress-program=bzip2 \
		-xf $bin_dir/$package/$package.tar.bz2 -C $inst_root
	elif [ ! -z "$net_addr" ] ; then
		echo "getting package $package via net ..."
		wget $net_addr/hdw-linux/hdw-linux-$hdw_version/binaries/${hdw_arch}-${hdw_arch_opt}/$package/${package}.tar.bz2 > /dev/null 2>&1
		retval=$?
		if [ "$retval" != "0" ] ; then
			echo "package not found at $net_addr, aborting ..."
			exit
		else
			echo "extracting $package to $inst_root ..."	
			tar --use-compress-program=bzip2 \
				-xf ${package}.tar.bz2 -C $inst_root
			rm ${package}.tar.bz2
			echo "done"
		fi
	else
		echo "sorry, package $package not found"
		exit 1
	fi

	# care about info/dir file
	echo "recreating info dir file ..."
	cd $inst_root/usr/share/info
	rm -f dir
	for f in *; do
		install-info $f dir 2>/dev/null
	done

	fi

# dist-install
elif [ "$d_install" = "1" ] ; then
	# check dist file
	if [ ! -f $dist_file ] ; then
		echo "$dist_file not found, aborting"
	else
		# install all distribution related packages
		for package in `cat $dist_file`; do
			# execute myelf
			auto=""
			[ "$auto_resolve_deps" = "1" ] && auto="-a"
			$0 $auto -b install $inst_root $package
		done
	fi
fi

