summaryrefslogblamecommitdiff
path: root/scripts/libutil.sh
blob: 229b275ea37d62458f3cb479482773e774324bcf (plain) (tree)


















































































































































































































































































                                                                                                                    
#!/bin/sh

# libutil.sh - Utility functions
#
# Copyright(c) 2005 Natanael Copa
#
# Distributed under GPL-2
#

VERSION=0.13.1

# echo to stderr
eecho() {
	echo $* >&2
}

# echo to stderr and die
die() {
	echo -n "$PROGRAM: " >&2
	eecho $*
	exit 1
}

die_unless_force() {
	echo "$PROGRAM: $*" >&2
	[ -z "$FORCE" ] && exit 1
}

# remove double / and ./ in pathnames
beautify_path() {
	echo "$1" | sed 's:/^[^\.]\./::g; s:/\{2,\}:/:g; s:/\./:/:g'
}

# check if parameter is an uri or not
is_uri() {
	echo "$1" | grep "^[a-z][a-z0-9+]*:/" >/dev/null
}

# check if parameter is an apk package (contains a / or .apk at the end)
is_apk() {
	#echo "$1" | grep '/' >/dev/null && return 0
	[ -z "${1%%*/*}" ] && return 0
	
	#echo "$1" | grep ".apk$" >/dev/null
	[ -z "${1%%*.apk}" ]
}

# check if path start with a '/'
is_absolute_path() {
	test -z "${1##/*}"
}

# if path dont start with '/' then append $PWD
get_absolute_path() {
	if is_absolute_path "$1" ; then
		echo "$1"
	else
		beautify_path "$PWD/$1"
	fi
}

# check if parameter has version number (i.e. if it is an pkgv or pkg)
has_version() {
	echo "$1" | grep -- '-[0-9].*' >/dev/null
}

# check if parameter has some kind of wildcard
has_wildcard() {
	echo "$1" | grep "[\*\?\[]" >/dev/null
}

# get the scheme for an uri (echo everything before the first ':')
get_uri_scheme() {
	echo "$1" | cut -d : -f 1
}

# remove version number from package name
rm_ver() {
	echo "$1" | sed 's/\(.*\)-[0-9].*/\1/'
}

# get version number from package name or file
get_ver() {
	basename "$1" .apk | sed 's/.*-\([0-9].*\)/\1/'
}

# initialize a temp directory
# $1 contains the variable name for the directory
# the directory will automatically be deleted upon exit
init_tmpdir() {
	local omask=`umask`
	local __tmpd="$APK_TMPDIR/$PROGRAM-${$}-`date +%s`"
	umask 077 || die "umask"
	mkdir "$__tmpd" || exit 1
	trap "rm -fr \"$__tmpd\"; exit" 0
	umask $omask
	eval "$1=\"$__tmpd\""
}

# remove files and empty dirs in specified list.
# also remove APK_LBUFILES from default.tdb
# environment:
#  ROOT:	all files are relative this path
#  VERBOSE: 	echo filenames to stdout
#  DRYRUN:  	don't delete anything, just simulate
my_rm() {
	rm "$1" 2>/dev/null || busybox rm "$1"
}

list_uninstall() {
	local f p 
	local root=${ROOT:-"/"}
	sort -r "$1" | while read f ; do
		p="`beautify_path \"$root/$f\"`"
		if [ "$DRYRUN" ] ; then
			[ "$VERBOSE" ] && echo "$p"
		else
			if [ -d "$p" ] ; then
				# try to remove dir, but ignore errors. It might
				if rmdir "$p" 2>/dev/null ; then
					[ "$VERBOSE" ] && echo "$p"
					[ "$2" ] && echo "$f" >> "$2"
				fi
			else
				my_rm "$p" && [ "$VERBOSE" ] && echo "$p"
				[ "$2" ] && echo "$f" >> "$2"
			fi
		fi
	done
	return 0
}

# list all lines that occur in first list but not second
# the files cannot contain duplicate lines.
list_subtract() {
	( 
		# first we find all uniq lines
		cat "$1" "$2" | sort | uniq -u 
		
		# then we combine uniq lines with first file ...
		cat "$1"

		# ...and find all duplicates. Those only exist in first file
	) | sort | uniq -d
}

# insert an element first in APK_PATH if its not already there
insert_apk_path() {
	if [ "$1" != "`echo "$APK_PATH" | cut -d\; -f1`" ] ; then
		[ "$APK_PATH" ] && APK_PATH=";$APK_PATH"
		APK_PATH="$1$APK_PATH"
	fi
}

lbu_filter() {
	# Ok... I give up. shell is too slow. lets do it in awk.
	awk 'BEGIN {
		APK_LBUDIRS="'"$APK_LBUDIRS"'";
		numdirs = split(APK_LBUDIRS, lbudir, ":");
		#precalc lengths to save a few cpu cycles in loop
		for (i = 1; i <= numdirs; i++)
			len[i] = length(lbudir[i]);
	}

	# main loop
	{
		for (i = 1; i <= numdirs; i++) {
			if (index($0, lbudir[i]) == 1 && (len[i] == length() || substr($0, len[i] + 1, 1) == "/")) {
				print $0;
			}
		}	
	}'
}

is_lbu_file() {
	# just run test
	[ "$(echo "$1" | lbu_filter)" ]
}

# assign a value to a global var, either from environment or
# from configuraion file
# usage: get_var VARIBALE_NAME DEFAULT_VALUE
get_var() {
	local var
	# first we check if the envvar is set
	eval "var=\$$1"
	if [ "$var" ] ; then
		echo "$var"
	elif [ -f ${APKTOOLS_CONF:="$ROOT/etc/apk.conf"} ] ; then
		# then we check the conf file
		var=`awk -F = '/^'$1'=/ { print $2 }' "$APKTOOLS_CONF"`
		if [ "$var" ] ; then
			echo "$var"
		else
			# else we use the default
			echo "$2"
		fi
	else
		# no conf file found use default
		echo "$2"
	fi
}

##########################################################
# last_pkgf
# find the latest package in a list, return 1 if not found
last_pkgf() {
	local pkgf last  status
	while read pkgf ; do
		apk_version -q -t "$pkgf" "$last"
		[ $? -eq 2 ] && last="$pkgf"
	done
	[ -z "$last" ] && return 1
	echo "$last"
}

###########################################################
# dump global variables
dump_env() {
	echo "ROOT=$ROOT"
	echo "APKTOOLS_CONF=$APKTOOLS_CONF"
	echo "APK_PATH=$APK_PATH"
	echo "APK_DBDIR=$APK_DBDIR"
	echo "APK_TMPDIR=$APK_TMPDIR"
	echo "APK_FETCH=$APK_FETCH"
	echo "APK_DATA=$APK_DATA"
	echo "APK_DATALEVEL=$APK_DATALEVEL"
	echo "APK_LIBS=$APK_LIBS"
	echo "PACKAGES=$PACKAGES"

	echo "APKDB=$APKDB"
	echo "APK_NOCOMPRESS=$APK_NOCOMPRESS"
	echo "REP_DIR=$REP_DIR"
	echo "REP_SCHEME=$REP_SCHEME"
	echo "CACHED_INDEX=$CACHED_INDEX"
}

#############################################################################
# init_globals sets up the global variables

APK_PREFIX_IN_PKG="`get_var APK_PREFIX_IN_PKG ''`"

ROOT="`get_var ROOT /`"
echo "$ROOT" | grep -v "^/" > /dev/null && ROOT="$PWD/$ROOT"

APKTOOLS_CONF="`get_var APKTOOLS_CONF \"$(beautify_path /etc/apk/apk.conf)\"`"
APK_PATH=`get_var APK_PATH ""`
APK_DBDIR="`get_var APK_DBDIR \"$(beautify_path \"$ROOT/var/db/apk\")\"`"
APK_DBDIR_IN_PKG="`get_var APK_DBDIR_IN_PKG ${APK_PREFIX_IN_PKG}var/db/apk`"
APK_TMPDIR="`get_var \"APK_TMPDIR\" /tmp`"
APK_ADD_TMP="`get_var \"APK_ADD_TMP\" \"$ROOT/usr/tmp\"`"
APK_DATA="`get_var APK_DATA \"$(beautify_path \"$ROOT/var/lib/apk\")\"`"
APK_KEEPCACHE="`get_var APK_KEEPCACHE no`"
APK_LIBS="`get_var APK_LIBS /lib/apk`"
PACKAGES="`get_var PACKAGES \"$(beautify_path \"$ROOT/var/cache/packages\")\"`"

APKDB="`beautify_path \"$APK_DBDIR\"`"
APK_NOCOMPRESS=`get_var APK_NOCOMPRESS ""`

INDEX="INDEX.md5.gz"
CACHED_INDEX="$APK_DATA/$INDEX"

APK_SUM=`get_var APK_SUM md5`
APK_MKSUM=`get_var APK_MKSUM "${APK_SUM}sum"`
APK_CHKSUM=`get_var APK_CHKSUM "${APK_SUM}sum -c"`

APK_DEFAULT_TDB=`get_var APK_DEFAULT_TDB "$APK_DATA/default.tdb"`
SFIC=`which sfic 2>/dev/null`
APK_GZSIGN_CERT=`get_var APK_GZSIGN_KEY /etc/apk/apk.crt`

# confdirs are a : spearate list of dirs relative $ROOT that are to be
# considered for local backups.
# for example: APK_LBUDIRS="etc:usr/local/etc"
APK_LBUDIRS=`get_var APK_LBUDIRS 'etc'`