#!/bin/sh -e
#
# $Id: functions.in,v 1.9 2004/08/03 15:26:50 ldv Exp $
# Copyright (C) 2003, 2004  Dmitry V. Levin <ldv@altlinux.org>
# 
# This file defines functions used by hasher scripts.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

unset CDPATH ||:
PROG="${0##*/}"

Info()
{
	printf %s\\n "${0##*/}: $*" >&2
}

Fatal()
{
	printf %s\\n "${0##*/}: $*" >&2
	exit 1
}

quiet=
verbose=
Verbose()
{
	[ -n "$verbose" ] || return 0
	printf %s\\n "${0##*/}: $*" >&2
}

print_version()
{
	local prog
	prog="$1" && shift
	cat <<EOF
$prog version 1.0.6
Written by Dmitry V. Levin <ldv@altlinux.org>

Copyright (C) 2003, 2004  Dmitry V. Levin <ldv@altlinux.org>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
	exit
}

# root, go away.
[ "$EUID" -gt 0 ] 2>/dev/null ||
	Fatal "please run me as unprivileged user."

# safe umask.
umask 022

# save current work directory.
saved_cwd="$(/bin/pwd)"

# hasher directory.
hasher_dir=/usr/share/hasher

# subconfig identifier.
number=

# target architecture.
def_target=i586
target=

# hasher-priv directory.
def_hasher_priv_dir=/usr/lib/hasher-priv
hasher_priv_dir=

# working directory.
workdir=

aptbox=
chroot=
entry=
no_stuff=
use_pty=
mountpoints=
no_sisyphus_check=
no_sisyphus_check_in=
no_sisyphus_check_out=

[ -n "$prog_apt_get" ] || prog_apt_get="apt-get"
[ -n "$prog_apt_cache" ] || prog_apt_cache="apt-cache"
[ -n "$prog_apt_config" ] || prog_apt_config="apt-config"
[ -n "$prog_genbasedir" ] || prog_genbasedir="genbasedir"
export prog_apt_get prog_apt_cache prog_apt_config prog_genbasedir

set_apt_vars()
{
	[ -n "$apt_prefix" ] || return 0

	[ -d "$apt_prefix" ] ||
		Fatal "$apt_prefix: directory not available."

	if printf %s "$apt_prefix" |grep -qs '[`"$\]'; then
		Fatal "$apt_prefix: illegal symbols in apt prefix."
	fi

	local apt_libdir="$apt_prefix/lib"
	[ -d "$apt_libdir" ] ||
		Fatal "$apt_libdir: directory not available."

	prog_apt_get="$apt_prefix/bin/apt-get"
	[ -x "$prog_apt_get" ] ||
		Fatal "$prog_apt_get: program not available."

	prog_apt_cache="$apt_prefix/bin/apt-cache"
	[ -x "$prog_apt_cache" ] ||
		Fatal "$prog_apt_cache: program not available."

	prog_apt_config="$apt_prefix/bin/apt-config"
	[ -x "$prog_apt_config" ] ||
		Fatal "$prog_apt_config: program not available."

	prog_genbasedir="$apt_prefix/bin/genbasedir"
	[ -x "$prog_genbasedir" ] ||
		Fatal "$prog_genbasedir: program not available."

	if [ -z "$LD_LIBRARY_PATH" ]; then
		LD_LIBRARY_PATH="$apt_libdir"
	else
		LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$apt_libdir"
	fi

	if printf %s "$LD_LIBRARY_PATH" |grep -qs '[`"$\]'; then
		Fatal "$LD_LIBRARY_PATH: illegal symbols in LD_LIBRARY_PATH."
	fi

	export apt_prefix LD_LIBRARY_PATH
}

APT_CONFIG=
set_workdir()
{
	workdir="$1"
	cd "$workdir" || return 1
	workdir="$(/bin/pwd)" || return 1

	[ -n "$(printf %s "$workdir" |tr -d /.)" ] ||
		Fatal "$workdir: illegal working directory."
	if printf %s "$workdir" |grep -qs '[`"$\]'; then
		Fatal "$workdir: illegal symbols in pathname."
	fi
	[ -w . ] || Fatal "unwritable working directory."

	Verbose "changed working directory to \`$workdir'"
	aptbox="$workdir/aptbox"
	chroot="$workdir/chroot"
	entry="$chroot/.host/entry"
	export APT_CONFIG="$aptbox/etc/apt/apt.conf"
}

hash=
rpm_verbose=
exclude_docs=

# set hash and rpm_verbose variables.
check_tty()
{
	[ -n "$verbose" ] && tty -s <&1 &&
		hash=-h ||
		hash=

	rpm_verbose="$verbose"
	if [ -z "$rpm_verbose" ]; then
		if [ -z "$quiet" ]; then
			rpm_verbose=-v
		fi
	fi
}

check_helpers()
{
	[ -d "${hasher_priv_dir:-$def_hasher_priv_dir}" ] ||
		Fatal "cannot access hasher-priv helper directory."

	getugid1="${hasher_priv_dir:-$def_hasher_priv_dir}/getugid1.sh"
	[ -x "$getugid1" ] ||
		Fatal "cannot access getugid1 helper."

	getugid2="${hasher_priv_dir:-$def_hasher_priv_dir}/getugid2.sh"
	[ -x "$getugid2" ] ||
		Fatal "cannot access getugid2 helper."

	chrootuid1="${hasher_priv_dir:-$def_hasher_priv_dir}/chrootuid1.sh"
	[ -x "$chrootuid1" ] ||
		Fatal "cannot access chrootuid1 helper."

	chrootuid2="${hasher_priv_dir:-$def_hasher_priv_dir}/chrootuid2.sh"
	[ -x "$chrootuid2" ] ||
		Fatal "cannot access chrootuid2 helper."

	makedev="${hasher_priv_dir:-$def_hasher_priv_dir}/makedev.sh"
	[ -x "$makedev" ] ||
		Fatal "cannot access makedev helper."
}

# assumed: cwd == workdir
purge_chroot_in()
{
	find chroot/.in/ -mindepth 1 -delete
}

# assumed: cwd == workdir
purge_chroot_out()
{
	find chroot/.out/ -mindepth 1 -delete
}

# assumed: cwd == workdir
copy_chroot_incoming()
{
	purge_chroot_in
	install -p -m644 $verbose -- "$@" chroot/.in/ ||
		Fatal "failed to copy files."
}

# assumed: cwd == workdir
make_repo()
{
	mkdir -p $verbose -- repo/{{SRPMS,${target:-$def_target}/RPMS}.hasher,${target:-$def_target}/base}
}

# assumed: cwd == workdir, defined prog_genbasedir
update_repo()
{
	[ -z "$no_stuff" ] || return 0
	"$prog_genbasedir" --topdir=repo --no-oldhashfile --bz2only --mapi ${target:-$def_target} hasher &&
		Verbose "updated hasher repository indices." ||
		Fatal "failed to update hasher repository indices."
}

# assumed: defined variables: hash
update_RPM_database()
{
	rpmi -i $verbose $hash --dbpath "$aptbox/var/lib/rpm" $exclude_docs --ignoresize --noorder --noscripts --notriggers --justdb "$@"
		Verbose "RPM database updated." ||
		Fatal "RPM database update failed."
}

# assumed: defined APT_CONFIG, prog_apt_get
print_uris()
{
	[ -n "$APT_CONFIG" ] || Fatal "APT_CONFIG undefined."
	local out
	if ! out="$("$prog_apt_get" -q -y --print-uris install -- "$@" 2>&1)"; then
		printf %s\\n "$out" >&2
		Fatal "failed to calculate package file list."
	fi

	local pattern0="'\\([a-z]\\+\\):\\([^']\\+\\)' .*"
	local pattern1="'\\(file\\|copy\\):\\([^']\\+\\)' .*"

	local all_uris
	if ! all_uris="$(printf %s "$out" |sed -ne "s/^$pattern0/\\2/pg")"; then
		printf %s\\n "$out" >&2
		Fatal "failed to filter package file list."
	fi
	local uris
	if ! uris="$(printf %s "$out" |sed -ne "s/^$pattern1/\\2/pg")"; then
		printf %s\\n "$out" >&2
		Fatal "failed to filter package file list."
	fi

	if [ "$all_uris" != "$uris" ]; then
		printf %s\\n "$out" >&2
		Fatal "calculated package file list is not local."
	fi
	printf %s "$uris" &&
		Verbose "calculated package file list."
}

# quote argument for /.host/entry.
quote_arg()
{
	local out
	out="$(printf %s "$*" |sed -e 's/[\`"$]/\\&/g')" || return 1
	printf %s "$out"
}

entry_header='#!/bin/sh -e
TMPDIR="$HOME/tmp"
export TMPDIR
cd /.in'

entry_fakeroot_header='#!/bin/sh -e
if [ -z "$FAKEROOTKEY" -a "$USER" = "root" -a -x "/usr/bin/fakeroot" ]; then
	exec /usr/bin/fakeroot "$0" "$@"
fi
cd /.in'

