#!/bin/sh -e
# $Id: sisyphus_link_bin,v 1.3 2005/05/27 14:26:24 legion Exp $

. /etc/sisyphus/functions
. /etc/sisyphus/config

cd "$PREFIX"

export LC_ALL=C LANG=C LANGUAGE=C

verbose=
g_arch=
force_component=
component=contrib
interactive=
action=
tab_char="$(printf \\t)"

Usage() {
    [ "$1" = 0 ] || exec >&2
    cat << EOF
Usage: 
$PROG -a [options] <rpm> [<rpm> ...]
$PROG -d [options] <name> [<name> ...]

Options:
    -a, --add             add defined name to index list
    -d, --delete          delete defined name from index list
    -l, --list LISTNAME   define index list [default: $component]
    -i, --interactive     read 'name' from stdin.
    -h, --help            show this message
    --arch                define architecture [default: $arch]
    -A                    same as -a -v -i
    -D                    same as -d -v -i
EOF
    [ -n "$1" ] && exit "$1" || exit
}

WORKDIR=
exit_handler() {
    local rc=$?
    trap - EXIT
    [ -z "$WORKDIR" ] || rm -rf -- "$WORKDIR"
    exit $rc
}

show() {
    [ -z "$verbose" ] || Message "$*"
}

quote() {
    printf %s "$*" |sed -e 's/[+\`\"$]/\\&/g' || return 1 
}

do_add_package() {
    local rc=0
    local bin_component bin_list f l n s sn qn qsn
    for f in "$@"; do
	[ -z "$verbose" ] || printf '%s ' "$f"

	arch="$(printf %s "$f" | sed -ne 's,[[:space:]]\+,_,g; s,^.*\.\([^.]\+\)\.rpm$,\1,p')"
        if ! echo " $ARCHITECTURES " |fgrep -qs " $arch "; then
            Info "Unknown architecture: $arch"
	    continue
        fi

	[ -f "files/$arch/RPMS/$f" ] || { Info "Error: No such binary file: $f"; continue; }

	bin_component="$component"
	l="$(rpmquery -p --qf='%{name}\t%{arch}\t%{sourcerpm}\n' -- "files/$arch/RPMS/$f")" ||
	    { Info "Error: rpmquery failed: $f"; continue; }
	n="$(printf %s "$l" | cut -f1)"
	s="$(printf %s "$l" | cut -f3)"
	
	[ -f "$NEW_FILE_PREFIX/SRPMS/$s" ] || { Info "Error: No such source file: $s"; continue; }

	[ -z "$verbose" ] || printf '(%s) ' "$s"
	sn="$(rpmquery -p --qf '%{name}' "$NEW_FILE_PREFIX/SRPMS/$s")" ||
	    { Info "Error: rpmquery failed: $f"; continue; }

	bin_arch="$g_arch"
	[ -n "$g_arch" ] || bin_arch="$(printf %s "$l" | cut -f2)"

        if grep --mmap -m1 -qsxF "${n}${tab_char}${sn}" "files/list.$bin_arch".*; then
            Info "Error: $n already in lists"
            rc=1
            continue
        fi
	[ "${n#kernel-*}" = "$n" ] || bin_component=kernel
	[ -z "$force_component" ] || bin_component="$force_component"

	list="list.$bin_arch.$bin_component"
	[ -f "files/$list" ] || Fatal "cant find list: $(pwd)/files/$list" 
	printf '%s\t%s\n' "$n" "$sn" >> "$WORKDIR/$list"
	if [ -n "$verbose" ]; then
	    if grep --mmap -m1 -qsxF "${n}${tab_char}${sn}" "$WORKDIR/$list"; then 
		printf 'addition to %s succesed\n' "$list"
		continue
	    fi
	    printf 'addition to %s failed\n' "$list"
	fi
    done
    local l
    for l in "$WORKDIR/list".*; do
	[ "$l" != "$WORKDIR/list.*" ] || break
	sort -u -o "files/${l##*/}" "files/${l##*/}" "$l"
    done
    return $rc
}

do_del_package() {
    local rc=0
    local n l lists
    for n in $@; do
	lists="$(grep -Gl "^$n[[:space:]]" "files/list${g_arch:+.$g_arch}".* | grep -v 'list\.src')" || continue
	for l in $lists; do
	    subst "/^$n[[:space:]].*$/d" "$l" || rc=1
	    if [ -n "$verbose" ]; then
		printf 'removing %s from %s ' "$n" "$l"
		grep --mmap -m1 -qs "^$n[[:space:]].*$" "$l" && echo "failed" || echo "succesed"
	    fi
	done
    done
    return $rc
}

TEMP=`getopt -n $PROG -o h,v,A,D,l:,a,d,i -l help,verbose,arch:,list:,add,delete,interactive -- "$@"` || Usage
eval set -- "$TEMP"

while :; do
    case $1 in
        -a| --add)    action='add'
            ;;
	-A)
	    action='add'
	    interactive=1
	    verbose=-v	    
	    ;;
        -d| --delete) action='del'
            ;;
	-D)
	    action='del'
	    interactive=1
	    verbose=-v
	    ;;
        --arch) shift
	    if ! echo " $ARCHITECTURES " |fgrep -qs " $1 "; then
	        Fatal "Unknown architecture: $1"
	    fi
	    g_arch="$1"
            ;;
	-l| --list) shift
	    [ -z "$1" ] || component="$1"
	    ;;
        -i| --interactive) interactive=1
            ;;
	-v| --verbose) verbose=-v
	    ;;
	-h| --help) Usage 0
	    ;;
	--) shift; break
	    ;;
	*) Fatal "unrecognized option: $1"
	    ;;
    esac
    shift
done

pkgs="$@"
if [ -n "$interactive" ]; then
    arg=
    while read arg; do
        pkgs="$pkgs $arg"
    done
fi

# At least one argument, please.
if ! [ "${#pkgs}" -ge 1 ]; then
	Info "at least one argument is required."
	Usage
fi

trap exit_handler HUP INT QUIT TERM EXIT
WORKDIR="$(mktemp -d -t "$PROG.XXXXXXXXXX")"

[ -n "$action" ] || Usage 1
case $action in 
    add) do_add_package $pkgs ;;
    del) do_del_package $pkgs ;;
esac
