tazpkg diff modules/install @ rev 844

Finish modularization. Beta release: still have few FIXMEs and TODOs.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Mon Oct 05 03:53:47 2015 +0300 (2015-10-05)
parents
children ce7009ff237b
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/install	Mon Oct 05 03:53:47 2015 +0300
     1.3 @@ -0,0 +1,583 @@
     1.4 +#!/bin/sh
     1.5 +# TazPkg - Tiny autonomous zone packages manager, hg.slitaz.org/tazpkg
     1.6 +# install - TazPkg module
     1.7 +# Install packages
     1.8 +
     1.9 +
    1.10 +# Connect function libraries
    1.11 +. /lib/libtaz.sh
    1.12 +. /usr/lib/slitaz/libpkg.sh
    1.13 +
    1.14 +
    1.15 +# Get TazPkg working environment
    1.16 +. @@MODULES@@/getenv
    1.17 +# $CACHE_DIR will change, it based on unchanged value of $SAVE_CACHE_DIR
    1.18 +SAVE_CACHE_DIR="$CACHE_DIR"
    1.19 +
    1.20 +
    1.21 +. @@MODULES@@/find-depends
    1.22 +
    1.23 +
    1.24 +
    1.25 +
    1.26 +# Log TazPkg activity
    1.27 +
    1.28 +log_pkg() {
    1.29 +	debug "\nlog_pkg('$1')\n  PACKAGE='$PACKAGE'\n  VERSION='$VERSION'\n  EXTRAVERSION='$EXTRAVERSION'"
    1.30 +
    1.31 +	local extra
    1.32 +
    1.33 +	[ "$1" == 'Installed' ] && \
    1.34 +	extra=" - $(fgrep " $PACKAGE-$VERSION" "$PKGS_DB/installed.$SUM" | awk '{print $1}')"
    1.35 +	debug "  extra='$extra'"
    1.36 +
    1.37 +	[ -w "$LOG" ] &&
    1.38 +	echo "$(date +'%F %T') - $1 - $PACKAGE ($VERSION$EXTRAVERSION)$extra" >> $LOG
    1.39 +}
    1.40 +
    1.41 +
    1.42 +# get an already installed package from packages.equiv
    1.43 +
    1.44 +equivalent_pkg() {
    1.45 +	# input: $1 = package name (like "nano")
    1.46 +	local i rep rules rule out
    1.47 +
    1.48 +	rules=$(for rep in $PRIORITY; do
    1.49 +			grep -hs "^$1=" "$rep/packages.equiv"
    1.50 +		done | sed "s|^$1=||")
    1.51 +	debug "  >rules='$rules'"
    1.52 +
    1.53 +	for rule in $rules; do
    1.54 +		debug "  >rule='$rule'"
    1.55 +		case $rule in
    1.56 +			*:*)
    1.57 +				debug '-- x:x'
    1.58 +				# format 'alternative:newname'
    1.59 +				# if alternative is installed then substitute newname
    1.60 +				out="${rule#*:}"
    1.61 +				awk -F$'\t' -vp="${rule%:*}" '$1==p{exit 1}' "$PKGS_DB/installed.info" || break
    1.62 +				debug '-- x:x /'
    1.63 +				;;
    1.64 +			*)
    1.65 +				debug '-- x'
    1.66 +				# unconditional substitution
    1.67 +				out="$rule"
    1.68 +				awk -F$'\t' -vp="$rule" '$1==p{exit 1}' "$PKGS_DB/installed.info" || break
    1.69 +				debug '-- x /'
    1.70 +				;;
    1.71 +		esac
    1.72 +		unset out
    1.73 +	done
    1.74 +	debug '--'
    1.75 +	# if not found in packages.equiv then no substitution
    1.76 +	echo "${out:-$1}"
    1.77 +}
    1.78 +
    1.79 +
    1.80 +# Check and install all missing deps.
    1.81 +# Auto install or ask user then install all missing deps from local dir, CD-ROM,
    1.82 +# media or from the mirror.
    1.83 +
    1.84 +install_all_deps() {				# READY!!!
    1.85 +	# input: $1 = package file to check/install missing dependencies
    1.86 +	# ROOT READY
    1.87 +	# dep: equivalent_pkg.
    1.88 +
    1.89 +	debug "\ninstall_all_deps('$1')"
    1.90 +
    1.91 +	local TMP_DIR DEPENDS num missing_packages equiv pkg answer dir found pkgfile
    1.92 +
    1.93 +	# Check for missing deps listed in a receipt packages.
    1.94 +
    1.95 +	# Get the receipt's variable DEPENDS
    1.96 +	DEPENDS=$(
    1.97 +		TMP_DIR=$(mktemp -d); cd "$TMP_DIR"
    1.98 +		cpio --quiet -i receipt >/dev/null 2>&1
    1.99 +		. receipt; echo $DEPENDS
   1.100 +		rm -rf "$TMP_DIR"
   1.101 +	) < "$1"
   1.102 +
   1.103 +	unset num missing_packages
   1.104 +	for depend in $DEPENDS; do
   1.105 +		debug "  depend='$depend'"
   1.106 +		equiv=$(equivalent_pkg $depend)
   1.107 +		debug "  equiv='$equiv'\n"
   1.108 +		if [ ! -d "$INSTALLED/$equiv" ]; then
   1.109 +			missing_packages="$missing_packages $equiv"
   1.110 +			num=$((num+1))
   1.111 +		elif [ ! -f "$INSTALLED/$equiv/receipt" ]; then
   1.112 +			_ 'WARNING! Dependency loop between "%s" and "%s".' "$PACKAGE" "$equiv"
   1.113 +		fi
   1.114 +	done
   1.115 +
   1.116 +	# Nothing to install, exit function
   1.117 +	[ -z "$num" ] && return
   1.118 +
   1.119 +
   1.120 +	title "$(_ 'Tracking dependencies for package "%s"' "$PACKAGE")"
   1.121 +
   1.122 +	# Individual messages for each missing package
   1.123 +	for pkg in $missing_packages; do
   1.124 +		_ 'Missing package "%s"' "$pkg"
   1.125 +	done
   1.126 +
   1.127 +	footer "$(_p \
   1.128 +		'%s missing package to install.' \
   1.129 +		'%s missing packages to install.' "$num" \
   1.130 +		"$num")"
   1.131 +
   1.132 +
   1.133 +	if [ "$AUTO_INSTALL_DEPS" == 'yes' ]; then
   1.134 +		answer=0
   1.135 +	else
   1.136 +		newline
   1.137 +		confirm "$(_ 'Install all missing dependencies? (y/N)')"
   1.138 +		answer=$?
   1.139 +		newline
   1.140 +	fi
   1.141 +	debug "  answer='$answer'"
   1.142 +
   1.143 +	dir="$(dirname "$1")"
   1.144 +	debug "  dir='$dir'"
   1.145 +
   1.146 +	# We can install packages from /home/boot/packages at a boot time
   1.147 +	# Also we can prefer local packages over mirrored/cached using '--local' option
   1.148 +	[ "$dir" == '/home/boot/packages' ] && local='yes'
   1.149 +	debug "  local='$local'"
   1.150 +	[ -n "$local" ] && tazpkg mkdb "$dir" --forced >/dev/null
   1.151 +
   1.152 +
   1.153 +	# "--nodeps" option prevents to install dependencies
   1.154 +	if [ "$answer" -eq 0 -a -z "$nodeps" ]; then
   1.155 +		debug "  let's install missing packages"
   1.156 +		for pkg in $missing_packages; do
   1.157 +			debug "  pkg='$pkg'"
   1.158 +			if [ ! -d "$INSTALLED/$pkg" ]; then
   1.159 +				# Package not installed
   1.160 +
   1.161 +				found='0'
   1.162 +				# Prefer local packages
   1.163 +				if [ -n "$local" ]; then
   1.164 +					_ 'Checking if package "%s" exists in local list...' "$pkg"
   1.165 +					pkgfile=$(awk -F$'\t' -vp="$pkg" '
   1.166 +						$1==p{printf "%s-%s.tazpkg", $1, $2; exit 1}
   1.167 +						' "$dir/packages.info")
   1.168 +					if [ -n "$pkgfile" ]; then
   1.169 +						found='1'
   1.170 +						tazpkg install "$dir/$pkgfile"
   1.171 +					fi
   1.172 +				fi
   1.173 +				debug "    found='$found'"
   1.174 +
   1.175 +				# Install package from the mirror
   1.176 +				[ "$found" -eq 0 ] && tazpkg get-install "$pkg"
   1.177 +			fi
   1.178 +		done
   1.179 +	else
   1.180 +		# Answered 'No' to install dependencies, or '--nodeps' option given
   1.181 +		newline
   1.182 +		_ 'Leaving dependencies for package "%s" unresolved.' "$PACKAGE"
   1.183 +		_ 'The package is installed but will probably not work.'
   1.184 +		newline
   1.185 +	fi
   1.186 +}
   1.187 +
   1.188 +
   1.189 +# Extract a package with cpio and gzip/lzma.
   1.190 +
   1.191 +extract_package() {
   1.192 +	# input: $1 - path to package to be extracted; package should be in the current dir
   1.193 +	# ROOT INDEPENDENT
   1.194 +	action 'Extracting package...'
   1.195 +
   1.196 +	# Extract "outer layer": cpio; remove the original package file
   1.197 +	cpio -idm --quiet < "$1" && rm -f "$1"
   1.198 +
   1.199 +	# "Inner layer" may vary
   1.200 +	if [ -f fs.cpio.lzma ]; then
   1.201 +		# "Plain" cpio.lzma
   1.202 +		unlzma < fs.cpio.lzma | cpio -idm --quiet && rm fs.cpio.lzma
   1.203 +	elif [ -f fs.cpio.gz ]; then
   1.204 +		# "Fast" cpio.gz (used to pack-then-install process in most of get-packages)
   1.205 +		zcat fs.cpio.gz | cpio -idm --quiet && rm fs.cpio.gz
   1.206 +	fi
   1.207 +
   1.208 +	status
   1.209 +}
   1.210 +
   1.211 +
   1.212 +# Print short package description
   1.213 +
   1.214 +print_short_description() {
   1.215 +	# TODO: undigest repo support? priority...
   1.216 +	# ROOT READY
   1.217 +	local short_desc=''
   1.218 +
   1.219 +	# Try to find localized short description
   1.220 +	for LC in $LANG ${LANG%_*}; do
   1.221 +		[ -e "$PKGS_DB/packages-desc.$LC" ] &&
   1.222 +			short_desc=$(awk -F$'\t' -vp="$1" '$1==p{print $2; exit}' "$PKGS_DB/packages-desc.$LC")
   1.223 +	done
   1.224 +
   1.225 +	# Try to find short description for mirrored package
   1.226 +	[ -z "$short_desc" -a -s "$PKGS_DB/packages.info" ] &&
   1.227 +		short_desc=$(awk -F$'\t' -vp="$1" '$1==p{print $4; exit}' "$PKGS_DB/packages.info")
   1.228 +
   1.229 +	[ -z "$short_desc" ] && short_desc="$SHORT_DESC"
   1.230 +
   1.231 +	longline "$short_desc"
   1.232 +}
   1.233 +
   1.234 +
   1.235 +grepesc() {
   1.236 +	sed 's/\[/\\[/g'
   1.237 +}
   1.238 +
   1.239 +
   1.240 +
   1.241 +
   1.242 +#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
   1.243 +
   1.244 +# Block of receipt function callers
   1.245 +# Why? "Bad" receipt sourcing can redefine some vital TazPkg variables.
   1.246 +# Few receipts function should be patched now.
   1.247 +
   1.248 +# Input: $1 = path to the receipt to be processed
   1.249 +
   1.250 +# Pre-install commands
   1.251 +call_pre_install() {
   1.252 +	local tmp
   1.253 +	if grep -q '^pre_install()' "$1"; then
   1.254 +		action 'Execute pre-install commands...'
   1.255 +		tmp="$(mktemp)"
   1.256 +		cp "$1" "$tmp"
   1.257 +		sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
   1.258 +		( . "$tmp"; pre_install "$root" )
   1.259 +		status
   1.260 +		rm "$tmp"
   1.261 +	fi
   1.262 +
   1.263 +}
   1.264 +
   1.265 +call_post_install() {
   1.266 +	local tmp
   1.267 +	if grep -q '^post_install()' "$1"; then
   1.268 +		action 'Execute post-install commands...'
   1.269 +		tmp="$(mktemp)"
   1.270 +		cp "$1" "$tmp"
   1.271 +		sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
   1.272 +		( . "$tmp"; post_install "$root" )
   1.273 +		status
   1.274 +		rm "$tmp"
   1.275 +	fi
   1.276 +}
   1.277 +
   1.278 +
   1.279 +#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
   1.280 +
   1.281 +
   1.282 +# This function installs a package in the rootfs.
   1.283 +
   1.284 +install_package() {
   1.285 +	# input: $1 = path to package to be installed
   1.286 +	# dep: install_all_deps, print_short_description, extract_package, grepesc.
   1.287 +
   1.288 +	debug "\ninstall_package('$1')"
   1.289 +	local dir
   1.290 +
   1.291 +	PACKAGE_FILE="$1"
   1.292 +	TMP_DIR="$(mktemp -d)"
   1.293 +
   1.294 +	# Get receipt's variables and functions
   1.295 +	{ cd "$TMP_DIR"; cpio --quiet -i receipt >/dev/null 2>&1; } < "$PACKAGE_FILE"
   1.296 +	# Why next code? "Bad" receipt sourcing can redefine some vital TazPkg variables.
   1.297 +	(
   1.298 +		. "$TMP_DIR/receipt"
   1.299 +		cat > "$TMP_DIR/receipt.var" <<EOT
   1.300 +PACKAGE="$PACKAGE"
   1.301 +VERSION="$VERSION"
   1.302 +EXTRAVERSION="$EXTRAVERSION"
   1.303 +CATEGORY="$CATEGORY"
   1.304 +SHORT_DESC="$SHORT_DESC"
   1.305 +WEB_SITE="$WEB_SITE"
   1.306 +TAGS="$TAGS"
   1.307 +DEPENDS="$DEPENDS"
   1.308 +CONFIG_FILES="$CONFIG_FILES"
   1.309 +PACKED_SIZE="$PACKED_SIZE"
   1.310 +UNPACKED_SIZE="$UNPACKED_SIZE"
   1.311 +EOT
   1.312 +		rm "$TMP_DIR/receipt"
   1.313 +	)
   1.314 +	. "$TMP_DIR/receipt.var"
   1.315 +
   1.316 +
   1.317 +	# Make sure folder exists on new installs or upgrades
   1.318 +	mkdir -p "$INSTALLED/$PACKAGE"
   1.319 +
   1.320 +	# Keep "modifiers" and "files.list" on upgrade
   1.321 +	find "$INSTALLED/$PACKAGE" -type f \( ! -name modifiers ! -name files.list \) -delete
   1.322 +
   1.323 +	# Update "installed.md5"
   1.324 +	# TODO: discontinue using 'installed.md5'
   1.325 +	touch "$PKGS_DB/installed.$SUM"
   1.326 +	sed -i "/ $(basename "$PACKAGE_FILE")$/d" "$PKGS_DB/installed.$SUM" 2>/dev/null
   1.327 +	cd "$(dirname "$PACKAGE_FILE")"
   1.328 +	$CHECKSUM "$(basename "$PACKAGE_FILE")" >> "$PKGS_DB/installed.$SUM"
   1.329 +
   1.330 +	# Resolve package dependencies before package installation
   1.331 +	install_all_deps "$PACKAGE_FILE"
   1.332 +
   1.333 +
   1.334 +	# TODO: why this list-processed in the $PKGS_DB?
   1.335 +	#[ -n "$INSTALL_LIST" ] && echo "$PACKAGE_FILE" >> "$PKGS_DB/$INSTALL_LIST-processed"
   1.336 +
   1.337 +	if [ -n "$sequence" ]; then
   1.338 +		title 'Installation of package "%s" (%s)' "$PACKAGE" "$sequence"
   1.339 +	else
   1.340 +		title 'Installation of package "%s"' "$PACKAGE"
   1.341 +	fi
   1.342 +
   1.343 +	print_short_description "$PACKAGE"
   1.344 +	separator '-'
   1.345 +
   1.346 +	action 'Copying package...'
   1.347 +	cp "$PACKAGE_FILE" "$TMP_DIR"
   1.348 +	status
   1.349 +
   1.350 +	cd "$TMP_DIR"
   1.351 +	extract_package "$(basename "$PACKAGE_FILE")"
   1.352 +
   1.353 +	# Include temporary receipt to get the right variables
   1.354 +	. "$TMP_DIR/receipt.var"
   1.355 +
   1.356 +	cd "$INSTALLED"
   1.357 +
   1.358 +
   1.359 +	# Get files to remove if upgrading
   1.360 +	# IFS here modified temporarily for processing filenames with spaces
   1.361 +	IFS=$'\n'
   1.362 +	if [ -f "$PACKAGE/files.list" ]; then
   1.363 +		while read file; do
   1.364 +			grep -q "^$(echo "$file" | grepesc)$" "$TMP_DIR/files.list" && continue
   1.365 +			for i in $(cat "$PACKAGE/modifiers" 2>/dev/null;
   1.366 +				fgrep -sl "$PACKAGE" */modifiers | cut -d/ -f1); do
   1.367 +				grep -qs "^$(echo "$file" | grepesc)$" "$i/files.list" && continue 2
   1.368 +			done
   1.369 +			echo "$file"
   1.370 +		done < "$PACKAGE/files.list" > "$TMP_DIR/files2remove.list"
   1.371 +	fi
   1.372 +	unset IFS
   1.373 +
   1.374 +
   1.375 +	# Remember modified packages
   1.376 +	action 'Remember modified packages...'
   1.377 +	{
   1.378 +		check=false
   1.379 +		# TODO: why '[' the special?
   1.380 +		# FIXME: we have files with spaces in our packages!
   1.381 +		for i in $(fgrep -v [ $TMP_DIR/files.list); do
   1.382 +			[ -e "$root$i" ] || continue
   1.383 +			[ -d "$root$i" ] && continue
   1.384 +			echo "- $i"
   1.385 +			check=true
   1.386 +		done ;
   1.387 +		$check && \
   1.388 +		for i in *; do
   1.389 +			[ "$i" == "$PACKAGE" ] && continue
   1.390 +			[ -s "$i/files.list" ] || continue
   1.391 +			awk "{ printf \"$i %s\\n\",\$1 }" < "$i/files.list"
   1.392 +		done;
   1.393 +	} | awk '
   1.394 +{
   1.395 +	if ($1 == "-" || file[$2] != "") {
   1.396 +		file[$2] = file[$2] " " $1
   1.397 +		if ($1 != "-") {
   1.398 +			if (pkg[$1] == "") all = all " " $1
   1.399 +			pkg[$1] = pkg[$1] " " $2
   1.400 +		}
   1.401 +	}
   1.402 +}
   1.403 +END {
   1.404 +	for (i = split(all, p, " "); i > 0; i--)
   1.405 +		for (j = split(pkg[p[i]], f, " "); j > 0; j--)
   1.406 +			printf "%s %s\n",p[i],f[j];
   1.407 +}
   1.408 +		' | while read dir file; do
   1.409 +		if grep -qs "^$dir$" "$PACKAGE/modifiers"; then
   1.410 +			# Do not overload an overloaded file !
   1.411 +			rm "$TMP_DIR/$file" 2>/dev/null
   1.412 +			continue
   1.413 +		fi
   1.414 +		grep -qs "^$PACKAGE$" "$dir/modifiers" && continue
   1.415 +		if [ -s "$dir/volatile.cpio.gz" ]; then
   1.416 +			# We can modify backed up files without notice
   1.417 +			zcat "$dir/volatile.cpio.gz" | cpio -t --quiet | \
   1.418 +				grep -q "^${file#/}$" && continue
   1.419 +		fi
   1.420 +		echo "$PACKAGE" >> "$dir/modifiers"
   1.421 +	done
   1.422 +	status
   1.423 +
   1.424 +
   1.425 +	cd "$TMP_DIR"
   1.426 +	# Copy receipt, etc.
   1.427 +	for file in receipt files.list description.txt $CHECKSUM; do
   1.428 +		[ -f "$file" ] && cp "$file" "$INSTALLED/$PACKAGE"
   1.429 +	done
   1.430 +
   1.431 +
   1.432 +	# Pre-install commands
   1.433 +	call_pre_install "$INSTALLED/$PACKAGE/receipt"
   1.434 +
   1.435 +
   1.436 +	if [ -n "$CONFIG_FILES" ]; then
   1.437 +		# Save "official" configuration files
   1.438 +		action 'Saving configuration files...'
   1.439 +		debug "\n"
   1.440 +
   1.441 +		cd fs
   1.442 +		local config_file
   1.443 +		for config_file in $CONFIG_FILES; do
   1.444 +			debug "  config_file: '$config_file'"
   1.445 +			find ${config_file#/} -type f 2>/dev/null
   1.446 +		done | cpio -o -H newc --quiet | gzip -9 > "$INSTALLED/$PACKAGE/volatile.cpio.gz"
   1.447 +		cd ..
   1.448 +
   1.449 +		if [ -z "$newconf" ]; then
   1.450 +			debug "  no '--newconf': clean official config files"
   1.451 +			# Keep user configuration files: remove "official" from fs tree
   1.452 +			for config_file in $CONFIG_FILES; do
   1.453 +				debug "    remove '$config_file'"
   1.454 +				[ -d "fs$config_file" ] && rm -r "fs$config_file"
   1.455 +				[ -e "fs$config_file" ] && rm    "fs$config_file"
   1.456 +			done
   1.457 +		fi
   1.458 +		# always '[ Done ]' status, unless '--newconf' is passed or not
   1.459 +		:; status
   1.460 +	fi
   1.461 +
   1.462 +
   1.463 +	action 'Installing package...'
   1.464 +	[ -n "$(busybox ls fs/* 2>/dev/null)" ] && cp -aLf fs/* "$root/"
   1.465 +	status
   1.466 +
   1.467 +
   1.468 +	if [ -s files2remove.list ]; then
   1.469 +		action 'Removing old files...'
   1.470 +		while read file; do
   1.471 +			dir="$root$file"
   1.472 +			# Remove specified file
   1.473 +			rm -f "$dir"
   1.474 +			# Recursive remove non-empty up-dirs
   1.475 +			while [ "$dir" != "$root/" ]; do
   1.476 +				dir=$(dirname "$dir")
   1.477 +				rmdir "$dir" 2>/dev/null || break
   1.478 +			done
   1.479 +		done < files2remove.list
   1.480 +		true
   1.481 +		status
   1.482 +	fi
   1.483 +
   1.484 +
   1.485 +	# Remove the temporary random directory.
   1.486 +	action "Removing all tmp files..."
   1.487 +	cd ..; rm -rf "$TMP_DIR"
   1.488 +	status
   1.489 +
   1.490 +
   1.491 +	# Post install commands
   1.492 +	call_post_install "$INSTALLED/$PACKAGE/receipt"
   1.493 +
   1.494 +
   1.495 +
   1.496 +
   1.497 +	# Update system databases
   1.498 +	# Updating DBs is important process, so not to hide such errors (localized):
   1.499 +	# chroot: can't execute '/usr/bin/***': No such file or directory
   1.500 +
   1.501 +	local fl="$INSTALLED/$PACKAGE/files.list" upd=0 ud um ui us uk
   1.502 +
   1.503 +	fgrep    /usr/share/applications/ "$fl" | fgrep -q .desktop && udesk='yes'
   1.504 +	fgrep -q /usr/share/mime "$fl" && umime='yes'
   1.505 +	fgrep -q /usr/share/icon/hicolor "$fl" && uicon='yes'
   1.506 +	fgrep -q /usr/share/glib-2.0/schemas "$fl" && uschm='yes'
   1.507 +	fgrep    /usr/lib/gdk-pixbuf "$fl" | fgrep -q .so && upixb='yes'
   1.508 +	fgrep -q /lib/modules "$fl" && ukrnl='yes'
   1.509 +
   1.510 +	if [ -n "$udesk$umime$uicon$uschm$upixb$ukrnl" ]; then
   1.511 +		action 'Update system databases...'
   1.512 +		upd=1
   1.513 +	fi
   1.514 +
   1.515 +	# package 'desktop-file-utils'
   1.516 +	[ -n "$udesk" ] && chroot "$root/" /usr/bin/update-desktop-database /usr/share/applications
   1.517 +	# package 'shared-mime-info'
   1.518 +	[ -n "$umime" ] && chroot "$root/" /usr/bin/update-mime-database /usr/share/mime
   1.519 +	# packages 'gtk+', 'gtk+3'
   1.520 +	[ -n "$uicon" ] && chroot "$root/" /usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor
   1.521 +	# package 'glib'
   1.522 +	[ -n "$uschm" ] && chroot "$root/" /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas
   1.523 +	# package 'gdk-pixbuf'
   1.524 +	[ -n "$upixb" ] && chroot "$root/" /usr/bin/gdk-pixbuf-query-loaders --update-cache
   1.525 +	# packages 'busybox', 'kmod', 'depmod'
   1.526 +	[ -n "$ukrnl" ] && chroot "$root/" /sbin/depmod -a
   1.527 +
   1.528 +	[ "$upd" -eq 1 ] && status
   1.529 +
   1.530 +
   1.531 +
   1.532 +
   1.533 +	# Update installed.info
   1.534 +	SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
   1.535 +	# Remove newlines from some receipts
   1.536 +	DEPENDS=$(echo $DEPENDS)
   1.537 +	PKG_SUM="$(fgrep " $PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PKGS_DB/installed.$SUM" | cut -d' ' -f1)"
   1.538 +	ii="$PKGS_DB/installed.info"
   1.539 +	# Remove old entry
   1.540 +	sed -i "/^$PACKAGE	/d" "$ii"
   1.541 +	cat >> "$ii" <<EOT
   1.542 +$PACKAGE	$VERSION$EXTRAVERSION	$CATEGORY	$SHORT_DESC	$WEB_SITE	$TAGS	$SIZES	$DEPENDS	$PKG_SUM
   1.543 +EOT
   1.544 +	#awk -F$'\t' -vp="$PACKAGE" '$1==p' "$PKGS_DB/packages.info" > $ii
   1.545 +	TEMP_FILE="$(mktemp)"
   1.546 +	sort "$ii" > "$TEMP_FILE"; mv -f "$TEMP_FILE" "$ii"; chmod a+r "$ii"; unset ii
   1.547 +
   1.548 +	cd "$CUR_DIR"
   1.549 +	footer "$(_ 'Package "%s" (%s) is installed.' "$PACKAGE" "$VERSION$EXTRAVERSION")"
   1.550 +
   1.551 +	# Log this activity
   1.552 +	log_pkg Installed
   1.553 +
   1.554 +	# Remove package from upgrade list
   1.555 +	[ -s "$UP_LIST" ] && sed -i "/^$PACKAGE\$/d" "$UP_LIST"
   1.556 +}
   1.557 +
   1.558 +
   1.559 +
   1.560 +
   1.561 +#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
   1.562 +
   1.563 +
   1.564 +PACKAGE=$(
   1.565 +	tmp_dir=$(mktemp -d); cd "$tmp_dir"
   1.566 +	cpio --quiet -i receipt >/dev/null 2>&1
   1.567 +	. receipt; echo $PACKAGE
   1.568 +	rm -rf "$tmp_dir"
   1.569 +) < "$1"
   1.570 +
   1.571 +if [ -z "$forced" ]; then
   1.572 +	# Check if a package is already installed
   1.573 +	debug "\ncheck for installed package '$PACKAGE'"
   1.574 +
   1.575 +	awk -F$'\t' -vpv="$PACKAGE" '$1==pv { exit 1 }' "$PKGS_DB/installed.info"
   1.576 +
   1.577 +	if [ "$?" -eq 1 ]; then
   1.578 +		newline
   1.579 +		_ '"%s" package is already installed.' "$(colorize 34 "$PACKAGE")"
   1.580 +		longline "$(_ 'You can use the --forced option to force installation.')"
   1.581 +		newline
   1.582 +		exit 1
   1.583 +	fi
   1.584 +fi
   1.585 +
   1.586 +install_package "$(realpath "$1")"