#!/bin/sh -efu
# ***** BEGIN LICENSE BLOCK *****
# * Copyright (C) 2007  Alexey Gladkov <legion@altlinux.org>
# *
# * This program 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
# ***** END LICENSE BLOCK *****

export LC_ALL=C LANG=C LANGUAGE=C
export HOME="${HOME:-/root}"
export TMPDIR="${TMPDIR:-/tmp}"

. install2-sh-functions

PROG="${0##*/}"
socket_path="/tmp/alterator/browser-sock"
logfile="/tmp/basesystem.log"

notify() {
	[ -z "$AUTOINSTALL" ] || return 0
	alterator-mailbox-send "$1" ||:
}

simple_quote()
{
	sed 's,[\"],\\&,g'
}

rpminstall() {
	local out= code= fs=
	if [ -z "$AUTOINSTALL" ]; then
		if ! out="$(install2-rpm -i --socket="$socket_path" "$@" 2>&1)"; then
			printf %s\\n "$out" >&2

			fs="$(printf %s "$out" |
				sed 	-e '/installing package .* needs .* on the .* filesystem.*/!d' \
					-e 's#^installing package .* the \(.*\) filesystem.*#\1#' \
					-e 's#^$destdir#/#g' |
				sort -u |
				tr '\n' ' ')"

			if printf %s "$out" |grep -qs 'installing package .* needs .* inodes on the .* filesystem'; then
				code="DISKNODES"
			elif   printf %s "$out" |grep -qs 'installing package .* needs .* on the .* filesystem'; then
				code="DISKSPACE"
			fi

			if [ -n "$code" ]; then
				notify "error $code filesystems \"${fs% }\""
			else
				notify "error UNKNOWN msg \"$(echo "$out"|simple_quote)\""
			fi
			return 1
		else
			printf %s\\n "$out" >&2
		fi
	else
		rpm -iv "$@" ||:
	fi
}

max() {
	local n="$(wc -l < "$1")"
	echo "$(($n + 1))"
}

rpms_in="$destdir/.in"
rpms_in_type="fs"
create_in() {
	local max_fs max_swap fs
	fs="$(find-free-partition)"
	[ -n "$fs" ] ||
		fatal "no mointpoints found in \`$destdir'"
	max_fs="${fs%% *}"
	fs="${fs#* }"
	msg "Filesystem size [$fs]: $max_fs"

	max_swap="$(sed -ne 's#^\(MemFree\|SwapFree\):[[:space:]]*\([[:digit:]]\+\) kB#\2+#p' /proc/meminfo |tr -d '\n')0"
	max_swap="$(($max_swap))"
	msg "MemFree + SwapFree: $max_swap"

	if [ "$max_fs" -lt "$max_swap" ]; then
		rpms_in_type="swap"
		rpms_in="$destdir/.in.tmpfs"
		mkdir -p -- "$rpms_in"
		mount -n -t tmpfs tmpfs "$rpms_in"
		msg "\`.in' will be created in tmpfs"
	else
		rpms_in_type="fs"
		rpms_in="$fs/.in"
		mkdir -p -- "$rpms_in"
		msg "$rpms_in: will be used"
	fi
}

remove_in() {
	[ "$rpms_in_type" != "swap" ] || umount -l "$rpms_in"
	rm -rf -- "$rpms_in"
}

counter=0
download() {
	local p n
	while read p; do
		n="${p##*/}"
		msg "GET: '$p'"
		[ "$p" != "${p#/}" ] &&
			cp -s -L "$p" "$rpms_in/" ||
			curl -s -S --retry 5 --retry-delay 2 -o "$rpms_in/$n" "$p" < /dev/null
		printf %s\\n "$rpms_in/$n" >>"$rpms_in/manifest.all"
		notify "package \"$n\" step $counter"
		counter=$(($counter + 1))
	done
}

if [ "$#" -eq 0 ]; then
	echo "Usage: ${0##*/} <manifest>" >&2
	exit 1
fi
manifest="$1" && shift
notify "init #t"
create_in

### Prepare
mkdir -p -- \
	"$destdir/etc/rpm" \
	"$destdir/etc/sysconfig" \
	"$destdir/dev/pts" \
	"$destdir/var/lib/rpm" \
	"$destdir/$HOME" \
	"$destdir/$TMPDIR"

# rpm postinstall scripts need this
cp -at "$destdir/dev" -- /dev/null /dev/zero /dev/full /dev/random /dev/urandom /dev/console /dev/tty /dev/ptmx

# We need /etc/rpm/macros to install languages
[ ! -f "/etc/rpm/macros" ] || cp -a /etc/rpm/macros "$destdir/etc/rpm/macros"

# Init rpm database
rpm --initdb --dbpath "$destdir/var/lib/rpm"

>"$rpms_in/manifest.all"

notify "stage download-pkgs max $(max "$manifest")"
# reorder to get setup and filesystem first.
egrep    '/(filesystem|setup)-' -- "$manifest" |download
egrep -v '/(filesystem|setup)-' -- "$manifest" |download
notify "package \" \" step $(max "$manifest")"

notify "stage install-pkgs max $(max "$rpms_in/manifest.all")"
rc=
rpminstall --root "$destdir" -- "$rpms_in/manifest.all" >"$logfile" 2>&1 || rc=$?
[ -n "$rc" ] || notify "package \" \" step $(max "$rpms_in/manifest.all")"

remove_in
# Final report
[ -n "$rc" ] || notify "done #t"
