#!/bin/sh
##############################################################################
#
#  Copyright (c) 2013, Doremi Labs, Inc.
#    All rights reserved.
#
#  Redistribution in source or binary forms, with or without
#  modification, are NOT permitted.
#
#    Doremi Labs, Inc.
#    1020 Chestnut St.
#    Burbank, CA 91506
#    Tel : (818) 562 1101
#    Fax : (818) 562 1109
#
##############################################################################

. /doremi/etc/init.d/functions

PROGNAME="pkg_tool"
PROGVERSION="1.0.1"

# Default values
NO_CHECK=0					# Force package installation
DEFAULT_PLATFORM="dcp2000"			# Default platform value in case /etc/platform does not exist

# Directories
PATH_PKGS_DATABASE="/doremi/opt/pkgs/softwares"	# Database for all installed packages

# Log files
LOGFILE="/doremi/log/update.log"		# All update logs will go here
LOGLASTPKGS="/doremi/log/last_pkgs.log"		# All package install log will go here (shared with update.init)

# Files
BLACKLIST="/doremi/etc/blacklist.conf"
TMPBLACKLIST="/tmp/blacklist.conf"

# Binaries
LDBCTL="/doremi/sbin/ldbctl.out"

# Sanity check in case of RTC failure
YEAR=$( date +%Y )
if [ -z $YEAR ] || [ $YEAR -lt 2011 ]; then
	date -s 20110101
fi

# values from the package if available
PKGFILE="package filename"
PKG_PTH="package path"
PKG_TAG="content of package ./tag file"
PKG_NAM="content of package ./tag file or its name if not found"
PKG_VER="content of package ./version file"
PKG_DSC="content of package ./description file"
PKG_SIG="SignerID of package ./security.xml file"
PKG_ERR="package install.sh script return code"
PKG_IMO="package install mode, manual or at boot"
PKG_DAT="package install date"
PKG_LOG="package install log"
PKG_UNT="package uninstaller availability"

#
#  echo_log()
#	Print a log in LOGFILE
#
echo_log() {
	local CTIME="$(date | tr -d [:cntrl:])"

	echo "[${CTIME}]: $*" >> "${LOGFILE}"

	return 0
}

#
#  get_absolute_path()
#	Return the absolute path of a file
#	INPUT : file path
#	OUTPUT: absolute file path
#
get_absolute_path(){
	local FILE="$1"

	if ! echo "${FILE}" | grep -q "^\/"; then
		# Will return the absolute path of the file
		readlink -s -e "${FILE}" 2> /dev/null
	else
		# This is already an absolute path
		echo "${FILE}"
	fi

	return 0
}

#
#  pkg_install()
#	Install the specified package.
#	INPUT : filename.pk[gzx] ($1)
#	OUTPUT: 0 = success
#		other = error code
#
pkg_install() {
	local PACKAGE="$1"
	local TMP_UPDATE_LOG="/tmp/.update.log.swp"
	local tmppath="`mktemp -d`" || exit 1

	# Double check
	if ! test -r "${PACKAGE}"; then
		return 0
	fi

	echo_log "Installing package '${PACKAGE}'..."

	# Add a log if --no-check is enabled
	if is_no_check_enabled; then
		echo_log "WARNING: No check enabled: force package installation (ERRORS WILL BE IGNORED) !"
	fi

	# Process package
	mkdir -p ${tmppath}
	cd ${tmppath}

	# Check if file is blacklisted
	if [ -r $TMPBLACKLIST ]; then
		local pkgname=$(basename "${PACKAGE}" | tr -d [:cntrl:])
		echo "${pkgname%.???}" | grep -qf $TMPBLACKLIST
		if [ $? -eq 0 ]; then
			echo_log "ERROR: Package '${PACKAGE}' is blacklisted."
			is_no_check_enabled || return 255
		fi
	fi

	# Get file extension 'pkg', 'pkz', 'pkx' and extract package with the appropriate tool
	# If you add the support of a new extension, make sure to allow this extension in the script /doremi/etc/init.d/update.init.
	local extract_error=0
	case "`echo "${PACKAGE}" | tr -d [:cntrl:] | tail -c 3`" in
		pkg)
			tar zxvf "${PACKAGE}" > /dev/null 2>&1
			extract_error=$?
			;;
		pkz)
			unzip "${PACKAGE}" > /dev/null 2>&1
			extract_error=$?
			;;
		pkx)
			# For tarxz packages, it is possible to extract the content in two ways:
			# 1. tar -Jxvf ${PACKAGE}		(Not supported on DCP2000 products)
			# 2. xzdec ${PACKAGE} | tar xp		(Supported on all platforms)
			# For #2, the return code is a success (on DCP2000) even if xzdec fails. The variable PIPESTATUS will work on all platforms.

			xzdec "${PACKAGE}" 2> /dev/null | tar xp > /dev/null 2>&1
			extract_error=${PIPESTATUS}
			;;
		*)
			echo_log "ERROR: Package '${PACKAGE}' cannot be extracted: unknown format."
			return 255
			;;
	esac

	if [ "${extract_error}" -eq 0 ] ; then
		# Get the platform
		if [ -e /etc/platform ]; then
			local platform="$(cat /etc/platform)"
		else
			local platform="${DEFAULT_PLATFORM}"
		fi

		# Get some values from this package
		if [ -e ${tmppath}/tag ] ; then
			PKG_TAG="$( cat ${tmppath}/tag )"
		fi
		if [ -e ${tmppath}/version ] ; then
			PKG_VER="$( cat ${tmppath}/version )"
		fi
		if [ -e ${tmppath}/description ] ; then
			PKG_DSC="$( cat ${tmppath}/description )"
		fi
		if [ -e ${tmppath}/uninstall/uninstall.sh ] ; then
			PKG_UNT=1
		fi

		# Get the package name, with its tag or with its filename
		PKG_NAM="$(get_pkg_name)"

		if [ ! -r ${tmppath}/install.sh ] ; then
			echo_log "ERROR: Package '${PACKAGE}' is incomplete."
			return 255
		fi
		# Check platform file if available
		if [ ! -r ${tmppath}/platforms ] ; then
			# This file is mandatory for all platforms, except for DCP2000 / ShowVault
			if [ "${platform}" != "dcp2000" ]; then
				echo_log "ERROR: Package '${PACKAGE}' is incomplete."
				return 255
			fi
		else
			# Check if this package is authorized for this platform
			local PLATFORM_LOWER=$(echo "${platform}" | tr '[:upper:]' '[:lower:]')
			local PLATFORM_PKG_LOWER=""
			local isPlatformAuthorized=0

			for platform_pkg in $(cat "${tmppath}/platforms"); do
				PLATFORM_PKG_LOWER=$(echo "${platform_pkg}" | tr '[:upper:]' '[:lower:]')

				if [ "${PLATFORM_LOWER}" == "${PLATFORM_PKG_LOWER}" ]; then
					isPlatformAuthorized=1
					break
				fi
			done

			if [ "${isPlatformAuthorized}" -eq 0 ]; then
				echo_log "ERROR: Package '${PACKAGE}' is not authorized for this platform."
				return 255
			fi
		fi

		# Only root user can edit this configuration file
		if [ ! -f /etc/doremi/.pkg_check_skip ] ; then
			# Check package signature
			if [ ! -r ${tmppath}/security.xml ] ||
			   [ ! -r ${tmppath}/CHECKSUM ] ; then
				echo_log "ERROR: Package '${PACKAGE}' is incomplete."
				is_no_check_enabled || return 255
			else
				/doremi/sbin/pkg_check.out --quiet ${tmppath}/security.xml
				local pkg_check_errno=$?
				if [ $pkg_check_errno -ne 0 ] ; then
					echo_log "ERROR: Package license validation failed:"
					echo_log "-----------------------------------------"
					/doremi/sbin/pkg_check.out ${tmppath}/security.xml >> $LOGFILE 2>&1
					echo_log "-----------------------------------------"
					is_no_check_enabled || return $pkg_check_errno
				fi
				PKG_SIG="$( /doremi/sbin/pkg_check.out -v ${tmppath}/security.xml | grep "SignerID: " | awk -F "SignerID: " '{ print $2 }' )"
				local checksum="`md5sum ${tmppath}/CHECKSUM | cut -d \  -f1 | tr -d '[:space:]'`"
				cat ${tmppath}/security.xml | grep -q "<Value>$checksum</Value>"
				if [ $? -ne 0 ] ; then
					echo_log "ERROR: Unexpected CHECKSUM value: $checksum"
					is_no_check_enabled || return 255
				fi
				local oldpwd="`pwd`"
				cd ${tmppath}
				/usr/bin/md5sum -c CHECKSUM 2>&1 | grep -i failed >> $LOGFILE
				if [ $? -eq 0 ]; then
					echo_log "ERROR: Package integrity checks failed."
					is_no_check_enabled || return 255
				fi
				cd ${oldpwd}
			fi
		fi

		# Check the release version - old version are not authorized
		# This check is not available for DCP2000 product
		if [ "${platform}" != "dcp2000" ]; then
			# Check if the package is an IMS installation file
			if [ -e ${tmppath}/package.tar.xz ]; then
				local softnum=$(ver2num $(cat ${tmppath}/version))
				local softmin=$(ver2num $(cat /etc/platform-release))
				if [ $softnum -lt $softmin ] ; then
					echo_log "ERROR: Software release shall be >= $(cat /etc/platform-release)."
					is_no_check_enabled || return 255
				fi
			fi
		fi

		# Let's install !
		local install_error=0

		# Cleanup current pkg log
		rm -f "${PKG_LOG}"

		# Make a copy of update.log to check the diff (before installation)
		if [ -e "/doremi/log/update.log" ] ; then
			cp -f "/doremi/log/update.log" "${TMP_UPDATE_LOG}"
		else
			touch "${TMP_UPDATE_LOG}"
		fi

		# Install package and redirect logs
		chmod +x ${tmppath}/install.sh
		${tmppath}/install.sh 2>&1 | tee -a "${PKG_LOG}" | tee -a "${LOGLASTPKGS}"

		# Get the return code of install.sh
		install_error=${PIPESTATUS[0]}

		# Double check if error code is 0 (some package is not correctly built)
		if [ "${install_error}" -eq 0 ] ; then
			if diff -u0 "${TMP_UPDATE_LOG}" "/doremi/log/update.log" | grep -q -i error; then
				echo_log "WARNING: some errors have been detected during installation !"
				install_error=1
                        fi
                fi

		# Last things to do before the cleanup
		# Install package informations and uninstaller, only on success
		if [ "${install_error}" -eq 0 ]; then
			if ! install_pkg_infos; then
				echo_log "WARNING: failed to install package information."
			fi
			if ! install_pkg_history; then
				echo_log "WARNING: failed to install package history."
			fi
			if ! install_pkg_uninstaller "${tmppath}"; then
				echo_log "WARNING: failed to install package uninstaller."
			fi
		fi

		# Cleanup
		rm -rf ${tmppath}

		return ${install_error}
	else
		echo_log "ERROR: Package '${PACKAGE}' cannot be extracted: extract tool is missing, or package is corrupted."
		return 255
	fi

	return 0
}

#
#  pkg_log()
#	Generate a SoftwareUpdate Doremi log record.
#
pkg_log() {
	if [ ! -e /var/lock/subsys/drmldbd ] ; then
		if [ -e /etc/init.d/smd.init ] ; then
			/etc/init.d/smd.init start 2>&1 > /dev/null
		elif [ -e /doremi/etc/init.d/drmldbd.init ] ; then
			/doremi/etc/init.d/drmldbd.init start 2>&1 > /dev/null
		fi
		sleep 3
	fi
	local severity=""
	if [ $PKG_ERR -ne 0 ]; then
		severity="Error"
	else
		severity="Information"
	fi
	${LDBCTL} -s SoftwareUpdate 			\
			"Severity=${severity}"		\
			"AuthId=root" 			\
			"SignerID=${PKG_SIG}"		\
			"PackageFilename=${PKGFILE}"	\
			"Tag=${PKG_TAG}"		\
			"Version=${PKG_VER}" 		\
			"Description=${PKG_DSC}"	|\
	${LDBCTL} -l
}

#
#  get_pkg_name()
#	Return the package name of the current package
#	From the documentation:
#		- The <package_name> is extracted from the ./tag file of the package.
#		- In case the ./tag file is missing (old package version), the directory will have
#		  the name of the package file without the filename extension. Eg: dcp2000_patch-2.2.4-0
#
get_pkg_name() {
	local PACKAGE_NAME=""

	# Try to find the package name with the tag
	# If not found, get the package name with its filename, without extension
	if [ "${PKG_TAG}" != "" ]; then
		PACKAGE_NAME=$(echo "${PKG_TAG}" | head -1)
	else
		PACKAGE_NAME="${PKGFILE%.*}"
	fi

	# Format the package name (the order is important)
	PACKAGE_NAME=$(echo "${PACKAGE_NAME}" | sed -e 's/[^A-Za-z0-9._-]/_/g')		# Replace invalid characters and other spaces with _
	PACKAGE_NAME=$(echo "${PACKAGE_NAME}" | sed -u -e 's/_*_/_/g')			# Replace continuous occurrences of _ with only one _
	PACKAGE_NAME=$(echo "${PACKAGE_NAME}" | sed -u -e 's/^_*//' -e 's/_*$//')	# Remove underscores at the beginning and at the end
	PACKAGE_NAME=$(echo "${PACKAGE_NAME}" | tr '[:upper:]' '[:lower:]')		# Convert to a lower string

	echo "${PACKAGE_NAME}"

	return 0
}

#
#  get_pkg_install_mode()
#	INPUT: $1: <install> if it is an installation, <uninstall> if it is an uninstallation
#	Return if the package has been installed at boot or manually
#	Return code: always 0
#
get_pkg_install_mode() {
	local INSTALL_TYPE="$1"
	local INSTALL_TAG=""

	if   [ "${INSTALL_TYPE}" == "uninstall" ]; then
		INSTALL_TAG="uninstalled"
	elif [ "${INSTALL_TYPE}" == "install" ]; then
		INSTALL_TAG="installed"
	else
		INSTALL_TAG="installed"
	fi

	if [ "${RUNLEVEL}" == "S" ] && [ "${RC_ONCE}" == "1" ]; then
		echo "${INSTALL_TAG} at boot"
	else
		echo "manually ${INSTALL_TAG}"
	fi

	return 0
}

#
#  create_package_database()
#	Create the package database if it does not exist
#	Return 1 on failure, 0 on success
#
create_package_database() {
	local PATH_PKG_DB="${PATH_PKGS_DATABASE}/${PKG_NAM}"

	if test -d "${PATH_PKG_DB}"; then
		return 0
	elif [ "${PKG_NAM}" == "" ]; then
		return 1
	elif ! install -o root -g admin -m 0755 -d "${PATH_PKGS_DATABASE}" > /dev/null 2>&1; then
		return 1
	elif ! install -o root -g admin -m 0755 -d "${PATH_PKG_DB}" > /dev/null 2>&1; then
		return 1
	fi

	return 0
}

#
#  install_pkg_infos()
#	Install package informations in package database
#	This function works only if the package has been installed
#	Return 1 on failure, 0 on success
#
install_pkg_infos() {
	local PATH_PKG_DB="${PATH_PKGS_DATABASE}/${PKG_NAM}"

	# Create package database
	if ! create_package_database; then
		return 1
	fi

	# Install package informations
	echo "${PKG_NAM}"	> "${PATH_PKG_DB}/tag"			2> /dev/null
	echo "${PKG_VER}"	> "${PATH_PKG_DB}/version"		2> /dev/null
	echo "${PKG_DSC}"	> "${PATH_PKG_DB}/description" 		2> /dev/null
	echo "${PKG_DAT}"	> "${PATH_PKG_DB}/install_date" 	2> /dev/null
	echo "${PKG_IMO}"	> "${PATH_PKG_DB}/install_mode"		2> /dev/null
	cat  "${PKG_LOG}"       > "${PATH_PKG_DB}/install_log"		2> /dev/null

	# Set permissions
	find "${PATH_PKG_DB}" -type d -exec chmod 0755 {} \;		> /dev/null 2>&1
	find "${PATH_PKG_DB}" -type f -exec chmod 0644 {} \;		> /dev/null 2>&1
	find "${PATH_PKG_DB}" -exec chown root:admin {} \;		> /dev/null 2>&1

	return 0
}

#
#  install_pkg_history()
#	Install the package history, in CSV format
#	This function works only if the package has been installed / uninstalled
#	Return 1 on failure, 0 on success
#
install_pkg_history() {
	local PATH_PKG_HISTORY="${PATH_PKGS_DATABASE}/history.log"

	# Create database
	if ! install -o root -g admin -m 0755 -d "${PATH_PKGS_DATABASE}" > /dev/null 2>&1; then
		return 1
	fi

	# Update history (CSV format)
	echo "${PKG_DAT},${PKG_NAM},${PKG_VER},${PKG_IMO}" >> "${PATH_PKGS_DATABASE}/history.log" 2> /dev/null

	# Set permissions
	chmod 0644 "${PATH_PKGS_DATABASE}/history.log"		> /dev/null 2>&1
	chown root:admin "${PATH_PKGS_DATABASE}/history.log"	> /dev/null 2>&1

	return 0
}

#
#  uninstall_pkg_infos()
#	Uninstall package informations in package database
#	This function works only if the package has been uninstalled
#	Return 1 on failure, 0 on success
#
uninstall_pkg_infos(){
	local PATH_PKG_DB="${PATH_PKGS_DATABASE}/${PKG_NAM}"

	if ! rm -fr "${PATH_PKG_DB}" > /dev/null 2>&1; then
		return 1
	fi

	return 0
}

#
#  install_pkg_uninstaller()
#	INPUT: $1: The path where the package has been extracted
#	Install the package uninstaller, only if needed
#	Return 1 on failure, 0 on success
#
install_pkg_uninstaller() {
	local PATH_PKG_EXTRACT="$1"
	local PATH_PKG_EXTRACT_UNINSTALLER="${PATH_PKG_EXTRACT}/uninstall"
	local PATH_PKG_DB_UNINSTALLER="${PATH_PKGS_DATABASE}/${PKG_NAM}/uninstall"

	# Create package database
	if ! create_package_database; then
		return 1
	fi

	# This package does not contain an uninstaller, nothing to do
	if [ "${PKG_UNT}" != "1" ]; then
		return 0
	fi

	# Save uninstaller
	if ! test -d "${PATH_PKG_EXTRACT_UNINSTALLER}"; then
		# Package, or package uninstaller does not exist
		return 1
	elif ! rm -fr "${PATH_PKG_DB_UNINSTALLER}" > /dev/null 2>&1; then
		# Failed to remove old uninstaller (if any)
		return 1
	elif ! install -o root -g admin -m 0755 -d "${PATH_PKG_DB_UNINSTALLER}" > /dev/null 2>&1; then
		# Failed to create uninstaller directory
		return 1
	elif ! cp -f -a "${PATH_PKG_EXTRACT_UNINSTALLER}/." "${PATH_PKG_DB_UNINSTALLER}/" > /dev/null 2>&1; then
		# Failed to install new uninstaller
		return 1
	fi

	# Set permissions
	find "${PATH_PKG_DB_UNINSTALLER}" -type d -exec chmod 0755 {} \;	> /dev/null 2>&1
	find "${PATH_PKG_DB_UNINSTALLER}" -type f -exec chmod 0644 {} \;	> /dev/null 2>&1
	find "${PATH_PKG_DB_UNINSTALLER}" -exec chown root:admin {} \;		> /dev/null 2>&1

	return 0
}

#
#  process_pkg_install()
#	Process and install the specified package.
#	INPUT : path of the package ($1)
#	OUTPUT: 0 = success
#       	other = error code
#
process_pkg_install() {
	local PACKAGE=$(get_absolute_path "$1")

	if [ "${PACKAGE}" == "" ]; then
		echo "ERROR: you must supply a package path"
		return 1
	elif ! test -f "${PACKAGE}"; then
		echo "WARNING: package does not exist or is not a regular file: ${PACKAGE}"
		return 0
	fi

	ulimit -S -c 0 > /dev/null 2>&1

	# Build up a clean blacklist file by removing invalid/commented lines
	test -w $TMPBLACKLIST && rm -f $TMPBLACKLIST
	test -r $BLACKLIST    && cat $BLACKLIST | grep -v ^# | grep -v ^$ > $TMPBLACKLIST

	# Default values
	PKG_PTH="${PACKAGE}"
	PKG_TAG=""
	PKG_NAM=""
	PKG_VER=""
	PKG_DSC=""
	PKG_SIG="AAAAAAAAAAAAAAAAAAAAAAAAAAA="
	PKG_LOG="/tmp/pkg_log_$$.log"
	PKG_IMO=$(get_pkg_install_mode "install")
	PKG_DAT=$(date +"%FT%T%z")
	PKGFILE=$(basename "${PACKAGE}" | tr -d [:cntrl:])
	PKG_UNT=0

	# Install package
	pkg_install "${PACKAGE}"
	PKG_ERR=$?

	if [ ! -e /tmp/.software_update ] ; then
		# Generate SoftwareUpdate log record
		pkg_log
	else
		rm -f /tmp/.software_update
	fi

	# Cleanup
	test -w $TMPBLACKLIST && rm -f $TMPBLACKLIST
	rm -f "${PKG_LOG}"

	return ${PKG_ERR}
}

#
#  pkg_uninstall()
#	Uninstall package informations in package database
#	This function works only if the package has been uninstalled
#	Return 0 on success, error_code on failure
#
pkg_uninstall(){
	local PATH_PKG_DB_UNINSTALLER="$1"
	local TMP_UPDATE_LOG="/tmp/.update.log.swp"
	local FULL_PACKAGE_NAME=""

	# Double check
	if ! test -d "${PATH_PKG_DB_UNINSTALLER}"; then
		return 0
	fi

	# Try to format the package name
	if [ "${PKG_VER}" != "" ]; then
		FULL_PACKAGE_NAME="${PKG_NAM} v${PKG_VER}"
	else
		FULL_PACKAGE_NAME="${PKG_NAM}"
	fi


	echo_log "Uninstalling package '${FULL_PACKAGE_NAME}'..."

	# make a copy of update.log to check the diff
	if [ -e "/doremi/log/update.log" ] ; then
		cp -f "/doremi/log/update.log" "${TMP_UPDATE_LOG}"
	else
		touch "${TMP_UPDATE_LOG}"
	fi

	# Add a log if --no-check is enabled
	if is_no_check_enabled; then
		echo_log "WARNING: No check enabled: force package uninstallation (errors will be ignored)"
	fi

	# Process uninstallation
	cd "${PATH_PKG_DB_UNINSTALLER}"

	# Sanity checks
	if ! test -r "${PATH_PKG_DB_UNINSTALLER}/uninstall.sh"; then
		echo_log "ERROR: Uninstaller of package '${PKG_NAM}' is incomplete."
		is_no_check_enabled || return 255
	fi

	# Let's uninstall !
	local uninstall_error=0

	chmod +x "${PATH_PKG_DB_UNINSTALLER}/uninstall.sh"
	"${PATH_PKG_DB_UNINSTALLER}/uninstall.sh"

	# Get the return code of uninstall.sh
	uninstall_error=$?

	# Double check if error code is 0 (some package is not correctly built)
	if [ "${uninstall_error}" -eq 0 ] ; then
		if diff -u0 "${TMP_UPDATE_LOG}" "/doremi/log/update.log" | grep -q -i error; then
			uninstall_error=1
		fi
	fi

	# Last things to do
	# Uninstall package DB on success only
	if [ "${uninstall_error}" -eq 0 ]; then
		if ! install_pkg_history; then
			echo_log "WARNING: failed to install package history."
		fi
		if ! uninstall_pkg_infos; then
			echo_log "WARNING: failed to uninstall package information."
		fi
	fi

	return ${uninstall_error}
}

#
#  process_pkg_uninstall()
#       Uninstall the specified package.
#       INPUT : $1: path of the package database, or package tag
#       OUTPUT: 0 = success
#               other = error code
#
process_pkg_uninstall() {
	local PACKAGE="$1"
	local PACKAGE_TAG=""
	local PATH_PKG_DB=""
	local PATH_PKG_DB_UNINSTALLER=""

	# Sanity check
	if [ "${PACKAGE}" == "" ]; then
		echo "ERROR: you must supply the path of the package database, or the package tag"
		return 1
	fi

	# Remove any trailing /
	PACKAGE=$(echo "${PACKAGE}" | sed -u -e "s/\/*$//g")

	# Get the package tag from the argument
	if test -d "${PACKAGE}"; then
		PACKAGE_TAG="$(basename "${PACKAGE}")"
	else
		PACKAGE_TAG="${PACKAGE}"
	fi

	# Get the path of the package in the database and its uninstaller
	PATH_PKG_DB="${PATH_PKGS_DATABASE}/${PACKAGE_TAG}"
	PATH_PKG_DB_UNINSTALLER="${PATH_PKG_DB}/uninstall"

	# Sanity check
	if ! test -d "${PATH_PKG_DB}"; then
		echo "ERROR: unable to find package '${PACKAGE_TAG}' in the database"
		return 1
	elif ! test -d "${PATH_PKG_DB_UNINSTALLER}"; then
		echo "ERROR: no uninstaller available for package '${PACKAGE_TAG}'"
		return 1
        fi

	# Default values
	# PKG_NAM will be used to remove the package database with its name
	# Other values are, for now, not used.
	PKG_PTH="${PATH_PKG_DB}"
	PKG_TAG=$(cat "${PATH_PKG_DB}/tag" 2> /dev/null)
	PKG_NAM="${PACKAGE_TAG}"
	PKG_VER=$(cat "${PATH_PKG_DB}/version" 2> /dev/null)
	PKG_DSC=$(cat "${PATH_PKG_DB}/description" 2> /dev/null)
	PKG_SIG="AAAAAAAAAAAAAAAAAAAAAAAAAAA="
	PKG_LOG="/tmp/pkg_log_$$.log"
	PKG_IMO=$(get_pkg_install_mode "uninstall")
	PKG_DAT=$(date +"%FT%T%z")
	PKGFILE="${PATH_PKG_DB_UNINSTALLER}"
	PKG_UNT=0

	# Uninstall package
	local uninstall_error=0

	pkg_uninstall "${PATH_PKG_DB_UNINSTALLER}"
	uninstall_error=$?

	return ${uninstall_error}
}

#
#  set_no_check()
#	Set no check option only if current user level is root
#	Return 0 on success, 1 on failure
#
set_no_check(){
  local USER_ID="$(id -u)"

  # If current user is not root, do nothing
  if [ "${USER_ID}" -ne 0 ]; then
    echo_log "ERROR: Could not enable 'no check': option only available for root user."
    return 1
  fi

  # Set no check
  NO_CHECK=1

  return 0
}

#
#  is_no_check_enabled()
#	Return 0 if the <no check> option is enabled, else return 1
#
is_no_check_enabled(){
  if [ "${NO_CHECK}" != "1" ]; then
    return 1
  fi

  return 0
}


#
#  print_help()
#	Prints out the help of pkg_tool
#
print_help(){
	echo
	echo "${PROGNAME} v${PROGVERSION}"
	echo "Usage: ${PROGNAME} [OPTIONS]"
	echo
	echo "Manage the installation, logging and uninstallation of a package."
	echo
	echo "OPTIONS:"
	echo "  -h, --help"
	echo "        Print this help and exit"
	echo "  -i, --install <package>"
        echo "        Install the <package> and exit"
	echo "        <package>: - The path of the package file"
	echo "  -u, --uninstall <package>"
	echo "        Uninstall the <package>, only if an uninstaller is available, and exit"
	echo "        <package>: - Can be the path of the uninstaller in the package database"
	echo "                   - Can be the path of the package database"
        echo "                   - Can be the package name (tag) in the package database"
	echo

	return 0
}


#
# main()
#

# Copy of script in case if it updates itself
pkg_tool_sh=/tmp/pkg_tool

if [ "${PKG_TOOL_COPIED}" ]; then
        export PKG_TOOL_COPIED
else
        export PKG_TOOL_COPIED=1
	install -o root -g admin -m 0700 $0 ${pkg_tool_sh}
        exec ${pkg_tool_sh} $*
fi

# Check arguments
if test $# -eq 0; then
	print_help
	exit 0
fi

# Process arguments
while test $# -gt 0; do
	case "$1" in
		-h | --help)
			print_help
			exit 0
			;;
		--no-check)
			set_no_check
			;;
		-i | --install)
			shift
			process_pkg_install "$*"
			exit $?
			;;
		-u | --uninstall)
			shift
			process_pkg_uninstall "$*"
			exit $?
			;;
		* )
			echo "${PROGNAME}: unknown option $1" 1>&2
			echo "Try '${PROGNAME} --help' for more information." 1>&2
			exit 1
			;;
	esac
	shift
done

exit 0

