#!/bin/sh
# Cyrus database backends upgrade script
# (C) 2001 Ondřej Surý <ondrej@sury.org>
# distributed under the same licence as Cyrus IMAPd
#
# Run this script as root.  Ordinarily it will be run automatically in
# post-install.

set -e

export PATH=/sbin:/usr/sbin:/bin:/usr/bin

CONFIG_DIR="$(LC_ALL=C gawk '/^configdirectory:[[:blank:]]/ { print $2 }' < /etc/imapd.conf)"

BACKUP_DIR="/var/backup/cyrus-imapd/$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"

backupdb() {
    case "$2" in
	twoskip|skiplist|flat)
	    cp -a "$CONFIG_DIR/$1" "$BACKUP_DIR"
	    ;;
	quotalegacy)
	    echo "$0: Cannot backup $2 format" 1>&2
	    ;;
	*)
	    echo "$0: Unknown database format" 1>&2;
	    return 1
	    ;;
    esac
}

upgradedb() {
    TMPFILE="$(mktemp /tmp/"$1".XXXXXXXX)"
    /usr/lib/cyrus/bin/cvt_cyrusdb "$CONFIG_DIR/$1" "$2" "$TMPFILE" "$3"
    rm -f "$CONFIG_DIR/$1"
    mv "$TMPFILE" "$CONFIG_DIR/$1"
    chown cyrus:mail "$CONFIG_DIR/$1"
}

removedb() {
    rm -f "$CONFIG_DIR/$1"
}

touchdb() {
    touch "$CONFIG_DIR/$1"
    chown cyrus:mail "$CONFIG_DIR/$1"
}    

upgradealldb() {
    OLD_LIST="$2"
    NEW_LIST="$1"

    while read -r OLD_DBKEY OLD_DBVALUE ; do
	NEW_DBVALUE="$(LC_ALL=C gawk "/^${OLD_DBKEY}[[:blank:]]/ { print \$2 }" "$NEW_LIST")"

	if [ -z "${NEW_DBVALUE}" ]; then
	    echo "$0: Cannot upgrade $OLD_DBKEY from $OLD_DBVALUE to empty" 1>&2
	    return 1
	fi

	DO_UPGRADE_DB=
	if [ "${NEW_DBVALUE}" != "${OLD_DBVALUE}" ] ; then
	    echo "Upgrading $OLD_DBKEY from $OLD_DBVALUE to $NEW_DBVALUE ..."
	    DO_UPGRADE_DB=yes
	fi

	DBFILE=
	case "$OLD_DBKEY" in
	    DBENGINE)
		continue
		;;
	    ANNOTATION)
		DBFILE=annotations.db
		;;
	    MBOX)
		DBFILE=mailboxes.db
		;;
	    QUOTA|SUBS)
		if [ -n "${DO_UPGRADE_DB}" ]; then
		    echo "$0: Cannot upgrade ${OLD_DBKEY} database from ${OLD_DBVALUE} to ${NEW_DBVALUE} yet" 1>&2
		    return 1
		fi
		;;
	    DUPLICATE|PTS|STATUSCACHE|TLS|ZONEINFO|SEEN|CONVERSATIONS|SEARCH_INDEXED|SORTCACHE|SYNC_CACHE)
		;;
	    USERDENY)
		DBFILE=user_deny.db
		;;
	    BACKUP)
	        DBFILE=backups.db
		;;
	    *)
		echo "$0: Unknown type of DB: $OLD_DBKEY" 1>&2
		return 1
		;;
	esac

	# Just remove PTS, TLS and STATUSCACHE databases
	if [ -n "${DO_UPGRADE_DB}" ]; then
	    case "$OLD_DBKEY" in
		DUPLICATE)
		    removedb deliver.db
		    continue
		    ;;
		PTS)
		    removedb ptscache.db
		    continue
		    ;;
		TLS)
		    removedb tls_sessions.db
		    touchdb tls_sessions.db
		    continue
		    ;;
		STATUSCACHE)
		    removedb statuscache.db
		    continue
		    ;;
		SEEN)
		    continue
		    ;;
	    esac
	fi

	# Operate only if the database exists
	if [ -f "$CONFIG_DIR/$DBFILE" ]; then
	    # Backup database if we are changing format or upgrading Berkeley DB version
	    if [ -n "${DO_UPGRADE_DB}" ]; then
		backupdb "$DBFILE" "$OLD_DBVALUE" "$OLD_DBVERSION";
	    fi
	    # Upgrade cyrus database format
	    if [ -n "${DO_UPGRADE_DB}" ]; then
		upgradedb "$DBFILE" "$OLD_DBVALUE" "$NEW_DBVALUE"
	    fi
	fi
    done < "$OLD_LIST"
    return 0
}

upgradealldb /usr/lib/cyrus/cyrus-db-types.txt /usr/lib/cyrus/cyrus-db-types.active
RET="$?"
# Now set active db types to the current package
[ "$RET" -eq "0" ] && \
    cp -p /usr/lib/cyrus/cyrus-db-types.txt  /usr/lib/cyrus/cyrus-db-types.active

exit "$RET"
