summary refs log tree commit diff
path: root/noarch/package_utils
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2024-01-08 09:40:24 -0600
committerStarfall <us@starfall.systems>2024-01-08 09:40:24 -0600
commita91d41375fc87c958f0b4b2ec09d5bfa2bab9414 (patch)
tree5ecf2d3f5b5962bb2d317ad4ce1fddd88e8b0ed7 /noarch/package_utils
Initial commit HEAD main
Diffstat (limited to 'noarch/package_utils')
-rwxr-xr-xnoarch/package_utils818
1 files changed, 818 insertions, 0 deletions
diff --git a/noarch/package_utils b/noarch/package_utils
new file mode 100755
index 0000000..5483944
--- /dev/null
+++ b/noarch/package_utils
@@ -0,0 +1,818 @@
+#
+# This file contains 'package' run-time support utility functions.
+#
+# NOTE: This file must be "sourced" (not executed).
+#
+# WARNING: This file depends on functions from "run_time_utils" file.
+#
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# depends on "SCRIPT"
+#
+package_log_init() {
+	local PACKAGE
+	local PID
+	local USER_NAME
+
+	if [ -z "${SCRIPT}" ] ; then _abort_execution "'SCRIPT' is undefined" ; fi
+
+	PACKAGE="$1" ; if [ -z "${PACKAGE}" ] ; then _abort_execution "'PACKAGE' is unspecified" ; fi
+	USER_NAME="$(id -un)"
+	PID="$$"
+
+        PACKAGE_LOG_FILE="/tmp/${USER_NAME}_${PID}_${SCRIPT}_${PACKAGE}.log"
+        log_variable PACKAGE_LOG_FILE
+        rm -f "${PACKAGE_LOG_FILE}"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_get_arch_subdir() {
+	local ARCH
+	local ARCH_SUBDIR
+
+	if [ -n "${FORCEARCH}" ] ; then
+		ARCH="${FORCEARCH}"
+	elif { which rpm && rpm -q rpm; } >/dev/null 2>&1 ; then
+		log_message "using 'rpm'"
+		ARCH="$(rpm -q rpm --qf "%{ARCH}\n")"
+	elif which dpkg >/dev/null 2>&1 ; then
+		log_message "using 'dpkg'"
+		ARCH="$(dpkg --print-architecture)"
+	else
+		log_message "using 'uname'"
+		ARCH="$(uname -m)"
+        fi
+	log_variable ARCH
+
+	case "${ARCH}" in
+		"i386"|"i486"|"i586"|"i686")
+			ARCH_SUBDIR="i386"
+			;;
+
+		"x86_64"|"amd64")
+			ARCH_SUBDIR="x86_64"
+			;;
+
+		"arm")
+			ARCH_SUBDIR="arm"
+			;;
+
+		*)
+			_abort_execution "Unexpected architecture '${ARCH}'"
+			;;
+	esac
+	log_variable ARCH_SUBDIR
+
+        echo "${ARCH_SUBDIR}"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# depends on "DIST_DIR"
+#
+nls_init() {
+	local GETTEXT_RESULT
+	local NLS_TEST_MSG
+
+	if [ -z "${DIST_DIR}" ] ; then _abort_execution "'DIST_DIR' is undefined" ; fi
+
+
+	# NLS needs "TEXTDOMAIN" and "TEXTDOMAINDIR"
+
+	TEXTDOMAIN="install"
+	export TEXTDOMAIN
+	log_variable TEXTDOMAIN
+
+	TEXTDOMAINDIR="${DIST_DIR}/noarch/share/locale"
+	export TEXTDOMAINDIR
+	log_variable TEXTDOMAINDIR
+
+
+	GETTEXT_BINARY="$(2>/dev/null which gettext)"
+	export GETTEXT_BINARY
+	log_variable GETTEXT_BINARY
+
+	if [ -n "${GETTEXT_BINARY}" ] ; then
+		NLS_TEST_MSG="This is NLS test message"
+		GETTEXT_RESULT="$(LC_ALL="C" "${GETTEXT_BINARY}" "${NLS_TEST_MSG}")"
+		log_variable GETTEXT_RESULT
+		if [ "${NLS_TEST_MSG}" != "${GETTEXT_RESULT}" ] ; then
+			log_message "'gettext' is inoperable"
+			unset GETTEXT_BINARY
+		fi
+	fi
+
+
+	export ENVSUBST_BINARY="$(2>/dev/null which envsubst)"
+	log_variable ENVSUBST_BINARY
+
+	if [ -n "${ENVSUBST_BINARY}" ] ; then
+		ENVSUBST_RESULT="$(echo "${NLS_TEST_MSG}" | LC_ALL="C" "${ENVSUBST_BINARY}")"
+		log_variable ENVSUBST_RESULT
+		if [ "${NLS_TEST_MSG}" != "${ENVSUBST_RESULT}" ] ; then
+			log_message "'envsubst' is inoperable"
+			unset ENVSUBST_BINARY
+		fi
+	fi
+
+
+	if [ -n "${GETTEXT_BINARY}" ] ; then
+		if [ -n "${ENVSUBST_BINARY}" ] ; then
+			log_message "all necessary 'gettext' tools are available"
+			# Note: Implementation of "eval_gettext" was borrowed from "gettext.sh"
+			eval_gettext() {
+				# Note: "PATH" below is necessary for success of "export" if $("${ENVSUBST_BINARY}" --variables "$1") returns nothing
+				"${GETTEXT_BINARY}" "$1" | (export PATH $("${ENVSUBST_BINARY}" --variables "$1") ; "${ENVSUBST_BINARY}" "$1")
+			}
+		else
+			log_message "'gettext' without 'envsubst'"
+			eval_gettext() {
+				GETTEXT_RESULT="$(${GETTEXT_BINARY} "$1")"
+				eval "echo" "\"${GETTEXT_RESULT}\""
+			}
+		fi
+	else
+		log_message "not all necessary 'gettext' tools are available"
+		eval_gettext() {
+			eval "echo" "\"$1\""
+		}
+	fi
+
+	# WARNING: The whole message must be in single argument.
+	show_nls_message() {
+		local MESSAGE
+		local TRANSLATED
+
+		if [ $# -ne 1 ] ; then _abort_execution "Usage: show_nls_message \"message\"" ; fi
+		MESSAGE="$1"
+		log_variable MESSAGE
+		TRANSLATED="$(eval_gettext "${MESSAGE}")"
+		log_variable TRANSLATED
+		echo "${TRANSLATED}"
+	}
+
+	show_nls_message_no_nl() {
+		local MESSAGE
+		local TRANSLATED
+
+		if [ $# -ne 1 ] ; then _abort_execution "Usage: show_nls_message \"message\"" ; fi
+		MESSAGE="$1"
+		log_variable MESSAGE
+		TRANSLATED="$(eval_gettext "${MESSAGE}")"
+		log_variable TRANSLATED
+		echo -n "${TRANSLATED}"
+	}
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# depends on "OEM_FILE"
+#
+# $1 - field name
+#
+get_oem_field() {
+	local FIELD_NAME
+
+	if [ -z "${OEM_FILE}" ] ; then _abort_execution "'OEM_FILE' is undefined" ; fi
+
+	FIELD_NAME="$1"
+	[ -z "${FIELD_NAME}" ] && return 1
+
+	grep "^${FIELD_NAME}=" "${OEM_FILE}" 2>/dev/null | sed 's/\"//g' | sed "s/${FIELD_NAME}=\(.*\)/\1/"
+}
+
+#
+# depends on "OEM_FILE"
+#
+specify_vendor() {
+	if [ -z "${OEM_FILE}" ] ; then _abort_execution "'OEM_FILE' is undefined" ; fi
+	if [ ! -r "${OEM_FILE}" ] ; then _abort_execution "'${OEM_FILE}' is unavailable" ; fi
+
+	VENDOR="$(grep '^VENDOR=' "${OEM_FILE}" 2>/dev/null | sed 's/VENDOR=\(.*\)/\1/')"
+	log_variable VENDOR
+	if [ -z "${VENDOR}" ] ; then _abort_execution "'VENDOR' is unspecified" ; fi
+
+	VENDOR_UC="$(echo "${VENDOR}" | tr a-z A-Z)"
+	VENDOR_LC="$(echo "${VENDOR}" | tr A-Z a-z)"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# depends on "SCRIPTS_DIR"
+#
+environment_init() {
+	if [ -z "${SCRIPTS_DIR}" ] ; then _abort_execution "'SCRIPTS_DIR' is undefined" ; fi
+
+	SCRIPT="$1"
+
+	unset DBUS_SESSION_BUS_ADDRESS
+
+	# - - - -
+	# Reset important environment variables to prevent unnecessary
+	# propagation between independent scripts invoking each other.
+	# - - - -
+	unset DIST_DIR
+	unset DIST_VERSION
+	unset DIST_VERSION_FILE
+	unset INSTALL_DIR
+	unset INSTALL_LOG_FILE
+	unset OEM_FILE
+	unset PACKAGE
+	unset PACKAGE_DIR
+	unset PACKAGE_NAME
+	unset PACKAGE_SUFFIX
+	unset REFERENCES_DIR
+	unset TEXTDOMAIN
+	unset TEXTDOMAINDIR
+	unset VENDOR
+	unset VENDOR_LC
+	unset VERSION
+	unset VERSION_FILE
+	# - - - -
+
+	export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
+
+	# Expecting: SCRIPTS_DIR="${DIST_DIR}/noarch"
+	DIST_DIR="$(absolute_dir_path "${SCRIPTS_DIR}/..")"
+	log_variable DIST_DIR
+
+	ARCH_SUBDIR="$(_get_arch_subdir)"
+
+	# "${DIST_DIR}/${ARCH_SUBDIR}" shall contain "gettext" and "envsubst"
+	PATH="$PATH:${DIST_DIR}/${ARCH_SUBDIR}" nls_init
+
+	if [ "${ARCH_SUBDIR}" = "x86_64" ]; then
+		PLSFX=64
+		LIBSFX=64
+		if [ ! -d /usr/lib${LIBSFX} ] ; then
+			LIBSFX=
+		fi
+	else
+		PLSFX=
+		LIBSFX=
+	fi
+
+	PACKAGE_DIR="${DIST_DIR}/noarch"
+	log_variable PACKAGE_DIR
+
+	OEM_FILE="${DIST_DIR}/noarch/oem.conf"
+	log_variable OEM_FILE
+	if [ -r "${OEM_FILE}" ] ; then
+		specify_vendor
+	fi
+
+	INSTALL_BASE_DIR="/opt"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# Old API
+#
+# depends on "VENDOR_LC"
+#
+_install_subdir() {
+	local INSTALL_SUBDIR
+	local PACKAGE_NAME
+	local PACKAGE_SUFFIX
+
+	if [ -z "${VENDOR_LC}" ] ; then _abort_execution "'VENDOR_LC' is undefined" ; fi
+
+	PACKAGE_NAME="$1" ; if [ -z "${PACKAGE_NAME}" ] ;then _abort_execution "'PACKAGE_NAME' is unspecified" ; fi
+	log_variable PACKAGE_NAME
+	PACKAGE_SUFFIX="$2" # 'PACKAGE_SUFFIX' is optional
+	log_variable PACKAGE_SUFFIX
+
+	if [ -z "${PACKAGE_SUFFIX}" ]; then
+		# common package
+		INSTALL_SUBDIR="smfp-common/${PACKAGE_NAME}"
+	else
+		# vendor specific package
+		INSTALL_SUBDIR="${VENDOR_LC}/${PACKAGE_NAME}"
+	fi
+	log_variable INSTALL_SUBDIR
+
+	echo "${INSTALL_SUBDIR}"
+}
+
+#
+# Old API
+#
+# depends on "INSTALL_BASE_DIR"
+# depends on "_install_subdir()", which depends on "VENDOR_LC"
+#
+_install_dir() {
+	local INSTALL_DIR
+	local INSTALL_SUBDIR
+	local PACKAGE_NAME
+	local PACKAGE_SUFFIX
+
+	if [ -z "${INSTALL_BASE_DIR}" ] ; then _abort_execution "'INSTALL_BASE_DIR' is undefined" ; fi
+	if [ -z "${VENDOR_LC}" ] ; then _abort_execution "'VENDOR_LC' is undefined" ; fi
+
+	PACKAGE_NAME="$1" ; if [ -z "${PACKAGE_NAME}" ] ;then _abort_execution "'PACKAGE_NAME' is unspecified" ; fi
+	log_variable PACKAGE_NAME
+	PACKAGE_SUFFIX="$2" # 'PACKAGE_SUFFIX' is optional
+	log_variable PACKAGE_SUFFIX
+
+	INSTALL_SUBDIR="$(_install_subdir "${PACKAGE_NAME}" "${PACKAGE_SUFFIX}")"
+	log_variable INSTALL_SUBDIR
+
+	INSTALL_DIR="${INSTALL_BASE_DIR}/${INSTALL_SUBDIR}"
+	log_variable INSTALL_DIR
+
+	echo "${INSTALL_DIR}"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#
+# depends on "_install_dir()", which depends on "INSTALL_BASE_DIR", "VENDOR_LC"
+#
+_version_file() {
+	local INSTALL_DIR
+	local PACKAGE_NAME
+	local PACKAGE_SUFFIX
+	local VERSION_FILE
+
+	PACKAGE_NAME="$1" ; if [ -z "${PACKAGE_NAME}" ] ;then _abort_execution "'PACKAGE_NAME' is unspecified" ; fi
+	log_variable PACKAGE_NAME
+	PACKAGE_SUFFIX="$2" # 'PACKAGE_SUFFIX' is optional
+	log_variable PACKAGE_SUFFIX
+
+	INSTALL_DIR="$(_install_dir "${PACKAGE_NAME}" "${PACKAGE_SUFFIX}")"
+
+	VERSION_FILE="${INSTALL_DIR}/.version"
+	log_variable VERSION_FILE
+
+	echo "${VERSION_FILE}"
+}
+
+#
+# depends on "DIST_DIR"
+#
+_dist_version_file() {
+	local DIST_VERSION_FILE
+	local PACKAGE_NAME
+	local PACKAGE_SUFFIX
+
+	if [ -z "${DIST_DIR}" ] ; then _abort_execution "'DIST_DIR' is undefined" ; fi
+
+	PACKAGE_NAME="$1" ; if [ -z "${PACKAGE_NAME}" ] ;then _abort_execution "'PACKAGE_NAME' is unspecified" ; fi
+	PACKAGE_SUFFIX="$2" # 'PACKAGE_SUFFIX' is optional
+
+	DIST_VERSION_FILE="${DIST_DIR}/noarch/.version-${PACKAGE_NAME}${PACKAGE_SUFFIX}"
+	log_variable DIST_VERSION_FILE
+
+	echo "${DIST_VERSION_FILE}"
+}
+
+_load_version_from_file() {
+	local VERSION_FILE
+	local VERSION_STRING
+
+	VERSION_FILE="$1"
+	#log_variable VERSION_FILE
+	VERSION_STRING="0"
+
+	# file exists and has non-zero size
+	if [ -s "${VERSION_FILE}" ] ; then
+	    VERSION_STRING="$(cat "${VERSION_FILE}")"
+	fi
+	log_variable VERSION_STRING
+
+	echo "${VERSION_STRING}"
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+load_package() {
+	local PACKAGE
+
+	PACKAGE="$1"
+	log_variable PACKAGE
+
+	# Note: uncomment the following line to create separate log files for each package
+	#package_log_init "${PACKAGE}"
+
+	# load 'package' API defaults
+	. "${SCRIPTS_DIR}/package_api_defaults"
+
+	# load 'package' API re-implementation
+	PACKAGE_FILE="${PACKAGE_DIR}/${PACKAGE}.pkg"
+	log_variable PACKAGE_FILE
+	if [ ! -r "${PACKAGE_FILE}" ] ; then  _abort_execution "package file '${PACKAGE_FILE}' is unavailable" ; fi
+	. "$PACKAGE_FILE"
+
+
+	# initialize package (new API)
+	package_on_load
+
+
+	# WARNING: Old API "package_init" depends on "INSTALL_DIR", "VENDOR_LC", "DIST_DIR"
+
+	PACKAGE_NAME="$(package_name)"
+	log_variable PACKAGE_NAME
+
+	PACKAGE_SUFFIX="$(package_suffix)"
+	log_variable PACKAGE_SUFFIX
+
+	#INSTALL_DIR="$(_install_dir "${PACKAGE_NAME}" "${PACKAGE_SUFFIX}")"
+	INSTALL_DIR="$(install_dir)"
+	log_variable INSTALL_DIR
+
+	REFERENCES_DIR="${INSTALL_DIR}/.usedby"
+	log_variable REFERENCES_DIR
+
+	INSTALL_LOG_FILE="${INSTALL_DIR}/.files"
+	log_variable INSTALL_LOG_FILE
+
+	# initialize package (old API)
+	package_init
+}
+
+################################################################################
+
+have_root_permissions() {
+	return "$(id -u)"
+}
+
+################################################################################
+# Copy files procedures
+
+#
+# registers installed item in install log
+#
+# depends on "INSTALL_LOG_FILE"
+#
+register_installed_item() {
+	local INSTALL_LOG_FILE_DIR
+	local ITEM
+
+	if [ -z "${INSTALL_LOG_FILE}" ] ; then _abort_execution "'INSTALL_LOG_FILE' is undefined" ; fi
+
+	ITEM="$1"
+	log_variable ITEM
+
+	if [ ! -f "${INSTALL_LOG_FILE}" ] ; then
+		INSTALL_LOG_FILE_DIR="$(dirname "${INSTALL_LOG_FILE}")"
+		if [ ! -d "${INSTALL_LOG_FILE_DIR}" ] ; then
+			# create necessary parent directories
+			log_message "mkdir -p ${INSTALL_LOG_FILE_DIR}"
+			mkdir -p "${INSTALL_LOG_FILE_DIR}"
+		fi
+	fi
+
+	echo "${ITEM}" >> "${INSTALL_LOG_FILE}"
+}
+
+install_log() {
+	while read src_dst
+	do
+		src="$( echo $src_dst | awk -F\" '{print $2}')"
+		dst="$(  echo $src_dst | awk -F\" '{print $4}')"
+		install "$src" "$dst"
+		chown root:root "$dst"
+		register_installed_item "${dst}"
+	done
+}
+
+install_p() {
+	local dest
+	local filename
+
+	if [ -n "$1" -a -n "$2" ]; then
+		dest="$2"
+		if [ -d "$dest" ] ; then
+			filename="$(basename "$1")"
+			dest="$2/$filename"
+		fi
+		register_installed_item "${dest}"
+		install "$1" "$dest"
+		return "$?"
+	fi
+	return 1
+}
+
+install_data_p() {
+	local dest
+	local filename
+
+	if [ -n "$1" -a -n "$2" ]; then
+		dest="$2"
+		if [ -d "$dest" ] ; then
+			filename="$(basename "$1")"
+			dest="$2/$filename"
+		fi
+		register_installed_item "${dest}"
+		install -m644 "$1" "$dest"
+		return "$?"
+	fi
+	return 1
+}
+
+mkdir_log() {
+	while read newdir
+	do
+		mkdir -p "$newdir"
+		register_installed_item "${newdir}"
+	done
+}
+
+mkdir_p() {
+	if [ -n "$1" ]; then
+		register_installed_item "$1"
+		mkdir -p "$1"
+		return "$?"
+	fi
+	return 1
+}
+
+lns_p() {
+	local dest
+	local filename
+
+	if [ -L "$2" ] ; then
+		rm -f -- "$2"
+	fi
+
+	if [ -n "$1" -a -n "$2" ]; then
+		dest="$2"
+		if [ -d "$dest" ] ; then
+			filename="$(basename "$1")"
+			dest="$2/$filename"
+		fi
+		register_installed_item "${dest}"
+		ln -sf "$1" "$dest"
+		return "$?"
+	fi
+	return 1
+}
+
+install_lns_p() {
+	local dest
+	local dest2
+	local filename1
+	local filename2
+
+	if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then
+		return 1
+	fi
+
+
+	dest="$2"
+	if [ -d "$dest" ] ; then
+		filename1="$(basename "$1")"
+		dest="$2/$filename1"
+	fi
+	register_installed_item "${dest}"
+	if ! install "$1" "$dest" ; then
+		return 1
+	fi
+
+
+	dest2="$3"
+	if [ -d "$dest2" ] ; then
+		filename2="$(basename "$1")"
+		dest2="$dest2/$filename2"
+	fi
+	register_installed_item "${dest2}"
+	ln -sf "$dest" "$dest2"
+	return "$?"
+}
+
+register_obsolete_install_lns_p() {
+	local dest
+	local dest2
+	local filename1
+	local filename2
+
+	if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then
+		return 1
+	fi
+
+
+	dest="$2"
+	if [ -d "$dest" ] ; then
+		filename1="$(basename "$1")"
+		dest="$2/$filename1"
+	fi
+	register_installed_item "${dest}"
+
+
+	dest2="$3"
+	if [ -d "$dest2" ] ; then
+		filename2="$(basename "$1")"
+		dest2="$dest2/$filename2"
+	fi
+	register_installed_item "${dest2}"
+
+	return 0
+}
+
+install_lns_data_p() {
+	local dest
+	local dest2
+	local filename1
+	local filename2
+
+	if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then
+		return 1
+	fi
+
+
+	dest="$2"
+	if [ -d "$dest" ] ; then
+		filename1="$(basename "$1")"
+		dest="$2/$filename1"
+	fi
+	register_installed_item "${dest}"
+	if ! install -m644 "$1" "$dest" ; then
+		return 1
+	fi
+
+
+	dest2="$3"
+	if [ -d "$dest2" ] ; then
+		filename2="$(basename "$1")"
+		dest2="$dest2/$filename2"
+	fi
+	register_installed_item "${dest2}"
+	ln -sf "$dest" "$dest2"
+	return "$?"
+}
+
+touch_p() {
+	if [ -z "$1" ] ; then
+		return 1
+	fi
+	register_installed_item "$1"
+	touch "$1"
+}
+
+# $1 - source directory
+# $2 - destination directory
+copy_directories() {
+	local DEST_DIR
+
+	DEST_DIR="$2"
+	if [ ! -d "${DEST_DIR}" ] ; then
+		show_nls_message "**** ERROR: Destination directory \${DEST_DIR} does not exist. Copy operation aborted."
+		return 1
+	fi
+
+	#destination directory must be ended by "/",
+	#but ended with only one "/",
+	#because "install" doesn't work correctly with SELinux context
+	#if we have double slash at the begining of the folder path
+	echo "${DEST_DIR}" | grep '/$' > /dev/null 2>&1
+	if [ "$?" = "1" ] ; then
+		dst_dir="$(echo "${DEST_DIR}"/)"
+	else
+		dst_dir="${DEST_DIR}"
+	fi
+
+	src_dir="$1"
+	if [ "$src_dir" ] && [ -d "$src_dir" ]; then
+		( cd "$src_dir" && find . -type d ) | grep -v ^\.$ | \
+			sed -e "s:\(^\./\)\(.*\):$dst_dir\2:"  | mkdir_log
+		( cd "$src_dir" && find . -type f -o -type l ) | \
+			sed -e "s:\(^\./\)\(.*\):\"$src_dir/\2\" \"$dst_dir\2\":"  | install_log
+	fi
+}
+
+################################################################################
+
+# Make reference to common (vendor independent) printer driver part
+register_dependency() {
+	local DEPENDENCIES
+	local DEPENDENCY
+	local DEPENDENCY_INSTALL_DIR
+	local DEPENDENCY_PACKAGE_NAME
+	local DEPENDENCY_PACKAGE_SUFFIX
+	local DEPENDENCY_REFERENCES_DIR
+	local REFERENCE_NAME
+	local LINK
+	local LINK_TARGET
+
+	# register references directory for deinstallation.
+	# Note: there is no need to create it here.
+	register_installed_item "${REFERENCES_DIR}"
+
+	DEPENDENCIES="$(dependencies)"
+	log_variable DEPENDENCIES
+	if [ -z "${DEPENDENCIES}" ] ; then return ; fi
+
+	for DEPENDENCY in ${DEPENDENCIES} ; do
+		DEPENDENCY_PACKAGE_NAME="$(echo "${DEPENDENCY}" | sed 's/\([^-]\+\)\(.*\)/\1/')"
+		log_variable DEPENDENCY_PACKAGE_NAME
+		# '
+		DEPENDENCY_PACKAGE_SUFFIX="$(echo "${DEPENDENCY}" | sed 's/\([^-]\+\)\(.*\)/\2/')"
+		log_variable DEPENDENCY_PACKAGE_SUFFIX
+		# '
+		DEPENDENCY_INSTALL_DIR="$(_install_dir "${DEPENDENCY_PACKAGE_NAME}" "${DEPENDENCY_PACKAGE_SUFFIX}")"
+		DEPENDENCY_REFERENCES_DIR="${DEPENDENCY_INSTALL_DIR}/.usedby"
+		log_variable DEPENDENCY_REFERENCES_DIR
+
+
+		if [ -z "${PACKAGE_SUFFIX}" ]; then
+			# common package
+			REFERENCE_NAME="${PACKAGE_NAME}"
+		else
+			# vendor specific package
+			# FIXME: scanner's backend expects '.usedby' link name equal to vendor's name"
+			#REFERENCE_NAME="${VENDOR_LC}-${PACKAGE_NAME}${PACKAGE_SUFFIX}"
+			REFERENCE_NAME="${VENDOR_LC}"
+		fi
+		log_variable REFERENCE_NAME
+
+		LINK="${DEPENDENCY_REFERENCES_DIR}/${REFERENCE_NAME}"
+		LINK_TARGET="${INSTALL_DIR}"
+
+		if [ ! -d "${DEPENDENCY_REFERENCES_DIR}" ] ; then
+			log_message "mkdir -p ${DEPENDENCY_REFERENCES_DIR}"
+			mkdir -p "${DEPENDENCY_REFERENCES_DIR}" | log_redirected_output
+		fi
+		if [ -L "${LINK}" ] ; then
+			log_message "rm -f -- ${LINK}"
+			rm -f -- "${LINK}" | log_redirected_output
+		fi
+		log_message "ln -sfv ${LINK_TARGET} ${LINK}"
+		ln -sfv "${LINK_TARGET}" "${LINK}" | log_redirected_output
+		register_installed_item "${LINK}"
+	done
+}
+
+#
+# Checks if there is no registered dependants
+#
+isUninstallPossible() {
+# return values:
+# 0(success): means uninstall is possible
+# !0(fail): means uninstall is not possible
+	log_variable PACKAGE_SUFFIX
+	log_variable INSTALL_LOG_FILE
+
+	# Temporary workaround to avoid uninstalling of the non-meta package multiple times
+	# INSTALL_LOG_FILE is used as an indicator that the package is installed, if it doesn't exist then do not proceed the package uninstalling
+	if [ "x${PACKAGE_SUFFIX}" != "x-meta" ] && ! [ -f "${INSTALL_LOG_FILE}" ]; then
+		log_message "'${INSTALL_LOG_FILE}' doesn't exist => package is not installed (already uninstalled)"
+		return 1
+	fi
+
+	# Try to remove references dir. It will fail if directory contains any reference link.
+	log_message "rmdir ${REFERENCES_DIR}"
+	rmdir "${REFERENCES_DIR}" 2>/dev/null
+
+	if [ -d "${REFERENCES_DIR}" ] ; then
+		log_message "dependants detected"
+		return 1
+	fi
+
+	log_message "no dependants detected"
+}
+
+remove_package_files() {
+	local ITEM
+	local LINES
+
+	if ! [ -f "${INSTALL_LOG_FILE}" ] ; then
+		return 1
+	fi
+
+	LINES="$( wc -l "${INSTALL_LOG_FILE}" | awk '{print $1}')"
+	for i in $(seq 1 $LINES ) ; do
+		ITEM="$(tail -$i "${INSTALL_LOG_FILE}" | head -1)"
+		log_variable ITEM
+		if [ -f "$ITEM" ] ; then
+			rm -f "$ITEM"
+		elif [ -h "$ITEM" ] ; then
+			rm -f "$ITEM"
+		elif [ -d "$ITEM" ] ; then
+			rmdir "$ITEM" 2>&1 | log_redirected_output
+		fi
+	done
+	rm -f "${INSTALL_LOG_FILE}"
+	return 0
+}
+
+################################################################################
+# Special output
+
+output_blank_line() {
+	echo ""
+}
+
+show_cut_line() {
+	echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
+}
+
+################################################################################
+
+log_message "EOF"