#!/bin/bash
#
#   repo-remove - remove a package entry from a given repo database file
#   @configure_input@
#
#   Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.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, see <http://www.gnu.org/licenses/>.

# gettext initialization
export TEXTDOMAIN='pacman'
export TEXTDOMAINDIR='@localedir@'

myver='@PACKAGE_VERSION@'
confdir='@sysconfdir@'

REPO_DB_FILE=""

msg() {
	local mesg=$1; shift
	printf "==> ${mesg}\n" "$@" >&1
}

msg2() {
	local mesg=$1; shift
	printf "  -> ${mesg}\n" "$@" >&1
}

warning() {
	local mesg=$1; shift
	printf "==> $(gettext "WARNING:") ${mesg}\n" "$@" >&2
}

error() {
	local mesg=$1; shift
	printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2
}

# print usage instructions
usage() {
	printf "$(gettext "repo-remove %s\n\n")" $myver
	printf "$(gettext "usage: %s <path-to-db> <packagename> ...\n\n")" "$0"
	printf "$(gettext "\
repo-remove will update a package database by removing the package name\n\
specified on the command line from the given repo database. Multiple\n\
packages to remove can be specified on the command line.\n\n")"
	echo "$(gettext "Example:  repo-remove /path/to/repo.db.tar.gz kernel26")"
}

version() {
	printf "repo-remove (pacman) %s\n" "$myver"
	printf "$(gettext "\
Copyright (C) 2002-2007 Judd Vinet <jvinet@zeroflux.org>.\n\n\
This is free software; see the source for copying conditions.\n\
There is NO WARRANTY, to the extent permitted by law.\n")"
}

# test if a file is a repository DB
test_repo_db_file () {
	if [ -f "$REPO_DB_FILE" ]; then
		if bsdtar -tf "$REPO_DB_FILE" | grep -q "/desc"; then
			return 0 # YES
		fi
	fi

	return 1 # NO
}

# remove existing entries from the DB
db_remove_entry() {
	pushd "$gstmpdir" 2>&1 >/dev/null

	# remove any other package in the DB with same name
	local existing
	for existing in *; do
		if [ "${existing%-*-*}" = "$1" ]; then
			msg2 "$(gettext "Removing existing package '%s'...")" "$existing"
			rm -rf "$existing"
		fi
	done

	popd 2>&1 >/dev/null
} # end db_remove_entry

# PROGRAM START

# determine whether we have gettext; make it a no-op if we do not
if [ ! $(type -t gettext) ]; then
	gettext() {
		echo "$@"
	}
fi

# check for help flags
if [ "$1" = "-h" -o "$1" = "--help" ]; then
	usage
	exit 0
fi

# check for version flags
if [ "$1" = "-V" -o "$1" = "--version" ]; then
	version
	exit 0
fi

# check for correct number of args
if [ $# -lt 2 ]; then
	usage
	exit 1
fi

# source system and user makepkg.conf
if [ -r "$confdir/makepkg.conf" ]; then
	source "$confdir/makepkg.conf"
else
	error "$(gettext "%s not found. Cannot continue.")" "$confdir/makepkg.conf"
	exit 1 # $E_CONFIG_ERROR
fi

if [ -r ~/.makepkg.conf ]; then
	source ~/.makepkg.conf
fi

# main routine
gstmpdir=$(mktemp -d /tmp/repo-remove.XXXXXXXXXX) || (\
	error "$(gettext "Cannot create temp directory for database building.")"; \
	exit 1)

success=0
# parse arguments
for arg in "$@"; do
	if [ -z "$REPO_DB_FILE" ]; then
		REPO_DB_FILE=$(readlink -f "$arg")
		if ! test_repo_db_file; then
			error "$(gettext "Repository file '%s' is not a proper pacman database.")\n" "$REPO_DB_FILE"
			exit 1
		elif [ -f "$REPO_DB_FILE" ]; then
			msg "$(gettext "Extracting database to a temporary location...")"
			bsdtar -xf "$REPO_DB_FILE" -C "$gstmpdir"
		fi
	else
		msg "$(gettext "Searching for package '%s'...")" "$arg"

		if db_remove_entry "$arg"; then
			success=1
		else
			error "$(gettext "Package matching '%s' not found.")" "$arg"
		fi
	fi
done

# if all operations were a success, re-zip database
if [ $success -eq 1 ]; then
	msg "$(gettext "Creating updated database file '%s'...")" "$REPO_DB_FILE"
	pushd "$gstmpdir" 2>&1 >/dev/null

	if [ -n "$(ls)" ]; then
		[ -f "${REPO_DB_FILE}.old" ] && rm "${REPO_DB_FILE}.old"
		[ -f "$REPO_DB_FILE" ] && mv "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
		case "$DB_COMPRESSION" in
			gz)  TAR_OPT="z" ;;
			bz2) TAR_OPT="j" ;;
			*)   warning "$(gettext "No compression set.")" ;;
		esac

		bsdtar -c${TAR_OPT}f "$REPO_DB_FILE" *
	else
		error "$(gettext "All packages have been removed from the database. Deleting '%s'.")" "$REPO_DB_FILE"
		rm "$REPO_DB_FILE"
	fi

	popd 2>&1 >/dev/null
else
	msg "$(gettext "No packages modified, nothing to do.")"
fi

# remove the temp directory used to unzip
[ -d "$gstmpdir" ] && rm -rf $gstmpdir

# vim: set ts=2 sw=2 noet: