#!/bin/sh -euf
# -*- mode: Shell-script; tab-width: 8; fill-column: 70; -*- 
# $Id: mkrpmbox,v 0.0.1 2006/05/19 15:19:32 legion Exp $ 
#
# ***** BEGIN LICENSE BLOCK ***** 
# * Copyright (C) 2006 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
# ***** END LICENSE BLOCK ***** 

PROG="${0##*/}"
version=0.0.1
verbose=
quiet=
force=
def_target=i586
importdb=1
target=

msg() {
    [ -n "$quiet" ] || printf %s\\n "$PROG: $*"
}

fatal() {
    printf %s\\n "$PROG: FATAL: $*" >&2
    exit 1
}

usage() {
    local rc="$1" && shift 
    [ "$#" -eq 0 ] || msg "$*"
    cat <<EOF

Usage: $PROG [Options] <work-dir> [<wrap-name>...]

<work-dir> must be valid writable directory.
<wrap-name> more wrapper name.

Options:
  --importdb        import system RPM database (used by default);
  --createdb        create empty RPM database;
  -t,--target=ARCH  target architecture;
  -f,--force        force rpmbox creation;
  -q,--quiet        try to be more quiet;
  -v,--verbose      print a message for each action;
  -V,--version      print program version and exit;
  -h,--help         show this text and exit.

Report bugs to http://bugs.altlinux.ru/

EOF
    exit "$rc"
}

print_version() {
    cat <<EOF
$PROG version $version
Written by Alexey Gladkov <legion@altlinux.org> 

Copyright (C) 2006  Alexey Gladkov <legion@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
}

TEMP=`getopt -n $PROG -o t:,f,q,v,V,h -l target:,importdb,createdb,force,quiet,verbose,version,help -- "$@"` || usage 1
eval set -- "$TEMP"

while :; do
	case "$1" in
	    --importdb) importdb=1
		;;
	    --createdb) importdb=
		;;
	    -t|--target) shift
		target="$1"
		;;
    	    -f|--force) force=1
		;;
	    -q|--quiet) quiet=-q
		;;
	    -v|--verbose) verbose=-v
		;;
	    -V|--version) print_version
	    	;;
	    -h|--help) usage 0
		;;
	    --) shift; break
		;;
	    *) fatal "unrecognized option: $1"
		;;
	esac
	shift
done

[ "$#" -ge 1 ] || usage 1 'Insufficient arguments.'

[ -d "$1" ] || exit 1
cd "$1" && shift
rpmbox="$(pwd)/rpmbox"

# exists already?
if [ -e rpmbox -o -L rpmbox ]; then
	[ -n "$force" ] || fatal "remove $rpmbox first."
	[ -d rpmbox ] || fatal "$rpmbox: invalid pathname."

	# empty dir?
	if rmdir -- rpmbox 2>/dev/null; then
		mkdir -m700 $verbose -- rpmbox
		cd rpmbox
	else
		cd rpmbox
		[ -d ./home/user -a -d ./var/lib/rpm ] ||
			fatal "$rpmbox: doesn't look valid."
	fi
else
	mkdir -m700 $verbose -- rpmbox
	cd rpmbox
fi

mkdir -p $verbose -- \
    ./home/user \
    ./var/tmp \
    ./var/lib/rpm \
    ./usr/src/RPM \
    #
BOX_HOME="$rpmbox/home/user"
for f in "$HOME/.rpmrc" "$HOME/.rpmmacros"; do
    [ ! -f "$f" ] || install -pm600 $verbose -- "$f" "$BOX_HOME/"
done

rpmshowrc="$(rpm --showrc)"
cur_arch="$(printf %s "$rpmshowrc" |sed -ne 's/^install arch[[:space:]]*:[[:space:]]*\([^[:space:]]\+\).*/\1/p')"
[ -n "$cur_arch" ] || fatal "Install arch not found"
if [ "$cur_arch" != "${target:-$def_target}" ]; then
    printf %s "$rpmshowrc" |
    grep -qs "^compatible archs[[:space:]]*:.*\<${target:-$def_target}\>" ||
	echo "arch_compat: $cur_arch: ${target:-$def_target}" >> "$BOX_HOME/.rpmrc"
fi

[ ! -f "$BOX_HOME/.rpmmacros" ] || sed -i "\,^[[:space:]]*%_\(topdir\|dbpath\)[[:space:]],d" "$BOX_HOME/.rpmmacros"
cat>>"$BOX_HOME/.rpmmacros"<<EOF
${target:+%rpmbox_arch $target}
%_topdir %(echo "\$RPMBOX")/usr/src/RPM
%_dbpath %(echo "\$RPMBOX")/var/lib/rpm
%_tmppath %(echo "\$RPMBOX")/var/tmp
EOF

cat >"retarget"<<EOF
#!/bin/sh -e
[ "\$#" -eq 1 ] || { printf %s\\\\n "Usage: \${0##*/} <new-target>"; exit 1; }
cd "\${0%/*}"
RPMBOX="\$(pwd)"
HOME="\$RPMBOX/${BOX_HOME#$rpmbox/}"
[ ! -f "\$HOME/.rpmrc" ] || sed -i '/^[[:space:]]*arch_compat:/d' "\$HOME/.rpmrc"
rpmshowrc="\$(rpm --showrc)"
cur_arch="\$(printf %s "\$rpmshowrc" |sed -ne 's/^install arch[[:space:]]*:[[:space:]]*\([^[:space:]]\+\).*/\1/p')"
[ -n "\$cur_arch" ] || printf %s\\\\n "Install arch not found" >&2
if [ "\$cur_arch" != "\$1" ]; then
    if ! printf %s "\$rpmshowrc" |grep -qs "^compatible archs[[:space:]]*:.*\<\$1\>"; then
	echo "arch_compat: \$cur_arch: \$1" >> "\$HOME/.rpmrc"
	printf %s\\\\n "\${0##*/}: compatibility added: \$cur_arch -> \$1"
    else
	printf %s\\\\n "\${0##*/}: architecture already compatible"
    fi
fi
EOF
chmod $verbose 700 -- "retarget"

for wrapper in rpm rpm2cpio rpmdb rpme rpmi rpminit rpmquery rpmsign rpmu rpmverify rpmlib "$@"; do
    prog=
    [ "$wrapper" = "rpmlib" ] || prog="$wrapper"
    cat >"$wrapper"<<EOF
#!/bin/sh -e
# -i --nodeps --badreloc --relocate=/=<RPMBOX>
\${LD_LIBRARY_PATH:+export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH"}
rname="\$(readlink -ve "\$0")"
export RPMBOX="\${rname%/*}"
export HOME="\$RPMBOX/${BOX_HOME#$rpmbox/}"
exec $prog "\$@"
EOF
    chmod $verbose 700 -- "$wrapper"
done
./rpminit

if [ -z "$importdb" ]; then
    spec="./usr/src/RPM/SPECS/null.spec"
    binrpm="./usr/src/RPM/RPMS/noarch/null-1.0-alt1.noarch.rpm"
    printf 'Name:null\nVersion:1.0\nRelease:alt1\nSummary:N\nGroup:System/Base\nLicense:GPL\nBuildArch:noarch\nConflicts: null < 1\n%%description\n%%prep\n%%setup -qcT\n%%install\n%%__mkdir_p %%buildroot\ntouch name\n%%triggerpostun -n null -- null > 1\ntrue\n%%files\n%%doc name\n' >"$spec"
    ./rpm -bb --nodeps --clean "$spec" >/dev/null 2>&1 && 
	./rpmi -i ${verbose:+-vh} --justdb --nodeps --noscripts --notriggers --ignoresize --noorder "$binrpm" && 
	./rpme -e null && 
	rm -f -- "$spec" "$binrpm"
    msg "Created RPM database in \`./var/lib/rpm/'."
else
    find /var/lib/rpm -type f -exec cp $verbose -ft ./var/lib/rpm -- \{\} \+
    msg "Imported RPM database in \`./var/lib/rpm/'."
fi
