#!@l_prefix@/lib/openpkg/bash
##
##  register -- OpenPKG Registry Command-Line Client
##  Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
##
##  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
##  All rights reserved. Licenses which grant limited permission to use,
##  copy, modify and distribute this software are available from the
##  OpenPKG GmbH.
##
##  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##

##
##  configuration
##

#   program name, version and date
progname="register"
progvers="1.1.3"
progdate="24-Aug-2007"

#   determine path to OpenPKG instance
PREFIX="@l_prefix@"
if [ ".${OPENPKG_PREFIX}" != . ]; then
    PREFIX="${OPENPKG_PREFIX}"
fi

#   determine rpm
rpm="$PREFIX/libexec/openpkg/rpm"
[ -x "$PREFIX/lib/openpkg/rpm" ] && rpm="$PREFIX/lib/openpkg/rpm"

#   http post
curl="$PREFIX/lib/openpkg/curl"
useragent="openpkg-$progname/$progvers"

error()
{
    echo "$progname:ERROR: $@" 1>&2
    exit 1
}

[ ".$PREFIX" = . ] && error "empty PREFIX not allowed"

##
##  read configuration unless already done during option parsing
##
sanitycheck()
{
    if [ ".$1" != . -a -r "$1" ]; then
        cat <"$1" | awk '
            BEGIN { rc=0 }
            !/^([A-Z][A-Z0-9_]+[A-Z0-9]="[^"]*")? *(#.*)?$/ { rc=1 }
            END { exit rc }' && return 0
    fi
    return 1
}

readconf()
{
    [ ".$REGISTRY_CONF" = . ] && return
    if [ -r "$REGISTRY_CONF" ]; then
        sanitycheck "$REGISTRY_CONF" && . "$REGISTRY_CONF"
    fi
}

readuuid()
{
    [ ".$REGISTRY_UUID" = . ] && return
    if [ -r "$REGISTRY_UUID" ]; then
        sanitycheck "$REGISTRY_UUID" && . "$REGISTRY_UUID"
    fi
}

readutil()
{
    [ ".$REGISTRY_UTIL" = . ] && return
    if [ -r "$REGISTRY_UTIL" ]; then
        sanitycheck "$REGISTRY_UTIL" && . "$REGISTRY_UTIL"
    fi
}

##
##  command line option parsing
##

#   default parameters
FQDN=`$PREFIX/lib/openpkg/shtool echo -e '%h%d'`

#   primary operations
op="automatic"

#   standard options
REGISTRY_AUTO="http://openpkg.org/go/autoregister"
REGISTRY_MODE="post"
REGISTRY_ARGS="http://registry.openpkg.org/register"
REGISTRY_USER=""
REGISTRY_LINK=""
REGISTRY_DESC="openpkg://${FQDN}${PREFIX}"

#   advanced options
#   we are called from rpm URL rewrite wrapper,
#   so defer PLAT and OREL lookup to avoid rpm loop
REGISTRY_PLAT=""
REGISTRY_OREL=""
REGISTRY_UUID="$PREFIX/etc/openpkg/uuid"
REGISTRY_CONF="$PREFIX/etc/openpkg/register.conf"
REGISTRY_PREP="$PREFIX/etc/openpkg/register.prep"
REGISTRY_TRAN="$PREFIX/etc/openpkg/register.tran"
REGISTRY_UTIL="$PREFIX/etc/openpkg/register.util"

#   amount of data being posted
REGISTRY_DATA="request,package,provides"

#   read baseline config early and allow options to override contents
readconf

#   debug options
verbose="no"
help="no"

#   iterate over argument line
declare -a a
declare -i i=0
while [ $# -gt 0 ]; do
    opt=$1
    case $opt in
        -*=*) arg=`echo "${opt}" | sed 's/^[-_a-zA-Z0-9]*=//'`
              opt=`echo "${opt}" | sed 's/=.*//'`
              ;;
           *) arg='' ;;
    esac
    case $opt in
        #   primary operations
        -P|--preparation ) op="preparation" ;;
        -T|--transaction ) op="transaction" ;;
        -U|--utilization ) op="utilization" ;;
        -C|--convenience ) op="convenience" ;;
        -I|--interaction ) op="interaction" ;;

        #   additional features
        -S|--printstatus ) op="printstatus" ;;
        -R|--rewriteurls ) op="rewriteurls" ;;

        #   standard options
        -m|--mode )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_MODE="$arg"
            ;;
        -a|--args )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_ARGS="$arg"
            ;;
        -u|--user )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_USER="$arg"
            ;;
        -l|--link )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_LINK="$arg"
            ;;
        -d|--desc )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_DESC="$arg"
            ;;

        #   advanced options
        --plat )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_PLAT="$arg"
            ;;
        --orel )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_VERS="$arg"
            ;;
        --uuid )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_UUID="$arg"
            ;;
        --conf )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_CONF="$arg"; readconf
            ;;
        --prep )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_PREP="$arg"
            ;;
        --tran )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_TRAN="$arg"
            ;;
        --util )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_UTIL="$arg"
            ;;
        --data )
            if [ ".$arg" = . ]; then shift; arg="$1"; fi
            if [ ".$arg" = . ]; then help="Missing argument to \"$opt\""; break; fi
            REGISTRY_DATA="$arg"
            ;;

        #   debug options
        -v|--verbose ) verbose="yes" ;;
        -h|--help    ) help="Usage"  ;;
        -*           ) help="Invalid option \`$opt'"; break ;;

        #   optional arguments
        * ) a[$i]="$opt"
            i=i+1
            ;;
    esac
    shift
done
set -- "${a[@]}"
unset i a

#   advanced options, lookup PLAT and OREL default for all modes
#   but those called from rpm URL rewrite mapper
if [ $op != "printstatus" -a $op != "rewriteurls" ]; then
    [ ".$REGISTRY_PLAT" = . ] && REGISTRY_PLAT="`$rpm --db-private --eval '%{l_platform -p}'`"
    [ ".$REGISTRY_OREL" = . ] && REGISTRY_OREL="`$rpm --db-private --eval '%{l_openpkg_release}'`"
fi

#   display error or usage message
if [ ".$help" != .no ]; then
    if [ ".$help" != ".Usage" ]; then
        echo "$progname:ERROR: $help" 1>&2
    fi
    echo "Usage: $progname [-u|--user=<user>] [-l|--link=<token>] [-d|--desc=<text>]"
    echo "       [-m|--mode=fake|post|wipe] [-a|--args=<args>]"
    echo "       [--plat=<text>] [--orel=<text>] [--uuid=<file>]"
    echo "       [--conf=<file>] [--prep=<file>] [--tran=<file>] [--util=<file>] [--data=<tag>[,<tag>...]]"
    echo "       [-P|--preparation] [-T|--transaction] [-U|--utilization]"
    echo "       [-C|--convenience] [-I|--interaction]"
    echo "       [-v|--verbose] [-h|--help]"
    echo "Usage: $progname -S|--printstatus"
    echo "Usage: $progname -R|--rewriteurls [[url]...]]"
    if [ ".$help" != ".Usage" ]; then
        exit 1
    else
        exit 0
    fi
fi

##
##  Primary operation Preparation
##
preparation()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        if [ ".$REGISTRY_PREP" != . ]; then
            if [ -f $REGISTRY_PREP ]; then
                cat </dev/null >$REGISTRY_PREP
            fi
        fi
        return
    fi

    [ ".$REGISTRY_USER" = . ] && error "missing information REGISTRY_USER"
    [ ".$REGISTRY_DESC" = . ] && error "missing information REGISTRY_DESC"
    [ ".$REGISTRY_PLAT" = . ] && error "missing information REGISTRY_PLAT"
    [ ".$REGISTRY_OREL" = . ] && error "missing information REGISTRY_OREL"
    [ ".$REGISTRY_UUID" = . ] && error "missing information REGISTRY_UUID"
    [ ".$REGISTRY_PREP" = . ] && error "missing information REGISTRY_PREP"

    if [ -r "$REGISTRY_UUID" ]; then
        sanitycheck "$REGISTRY_UUID" && . "$REGISTRY_UUID"
    fi
    [ ".$UUID_REGISTRY" = . ] && error "missing information UUID_REGISTRY"
    [ ".$UUID_INSTANCE" = . ] && error "missing information UUID_INSTANCE"
    [ ".$UUID_PLATFORM" = . ] && error "missing information UUID_PLATFORM"

    #   amount of data being posted
    Q='"'; I="    "; N=$'\n'; D=""

    echo "$REGISTRY_DATA" | grep request >/dev/null
    if [ $? = 0 ]; then
        D="${D}<?xml version=${Q}1.0${Q} encoding=${Q}iso-8859-1${Q} standalone=${Q}no${Q}?>${N}"
        D="${D}<!DOCTYPE registry${N}"
        D="${D}  PUBLIC ${Q}-//OpenPKG//DTD OpenPKG Registry 0.0.1//EN${Q}${N}"
        D="${D}  ${Q}http://registry.openpkg.org/registry.dtd${Q} []>${N}"
        D="${D}<registry>${N}"
        D="${D}${I}<request id=${Q}$UUID_REGISTRY${Q}${N}"
        D="${D}${I}${I}registry_user=${Q}$REGISTRY_USER${Q}${N}"
        [ ".$REGISTRY_LINK" != . ] && \
        D="${D}${I}${I}registry_link=${Q}$REGISTRY_LINK${Q}${N}" # optional
        D="${D}${I}${I}registry_desc=${Q}$REGISTRY_DESC${Q}${N}"
        D="${D}${I}${I}registry_plat=${Q}$REGISTRY_PLAT${Q}${N}"
        D="${D}${I}${I}registry_orel=${Q}$REGISTRY_OREL${Q}${N}"
        D="${D}${I}${I}uuid_registry=${Q}$UUID_REGISTRY${Q}${N}"
        D="${D}${I}${I}uuid_instance=${Q}$UUID_INSTANCE${Q}${N}"
        D="${D}${I}${I}uuid_platform=${Q}$UUID_PLATFORM${Q}${N}"

        echo "$REGISTRY_DATA" | grep package >/dev/null
        if [ $? = 0 ]; then
            D="${D}${I}>${N}"
            F=""
            F="${F}${I}${I}<package id=${Q}%{PKGID}${Q} name=${Q}%{NAME}${Q} version=${Q}%{VERSION}${Q} release=${Q}%{RELEASE}${Q}"
            echo "$REGISTRY_DATA" | grep provides >/dev/null
            if [ $? = 0 ]; then
                F="${F}>\n"
                F="${F}[${I}${I}${I}<provides name=${Q}%{PROVIDENAME}${Q} flag=${Q}%{PROVIDEFLAGS:depflags}${Q} version=${Q}%{PROVIDEVERSION}${Q}/>\n]"
                F="${F}${I}${I}</package>\n"
            else
                F="${F}/>\n"
            fi
            D="${D}`$rpm --db-private --qf \"${F}\" -qa | sed '/<package id="(none)"/,/<\/package>/d'`${N}"
            D="${D}    </request>${N}"
        else
            D="${D}${I}/>${N}"
        fi
        D="${D}</registry>${N}"
    fi
    echo "$D" | tee $REGISTRY_PREP
}

##
##  Primary operation Transaction
##
transaction()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        if [ ".$REGISTRY_TRAN" != . ]; then
            if [ -f $REGISTRY_TRAN ]; then
                cat </dev/null >$REGISTRY_TRAN
            fi
        fi
        return
    fi

    [ ".$REGISTRY_MODE" = . ] && error "missing information REGISTRY_MODE"
    [ ".$REGISTRY_ARGS" = . ] && error "missing information REGISTRY_ARGS"
    [ ".$REGISTRY_TRAN" = . ] && error "missing information REGISTRY_TRAN"

    if [ ".$REGISTRY_MODE" = .fake ]; then
        request=`awk '
            BEGIN { registry=0 }
            /<registry>/ { registry=1 }
            /<request / { if (registry) { print $0 } }
            /<\/registry>/ { registry=0 }' | \
            sed -e 's;^.*<request id=";;' -e 's;"$;;'`
        if [ ".$request" = . ]; then error "no request seen on stdin"; fi
        (
            echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>"
            echo "<!DOCTYPE registry"
            echo "  PUBLIC \"-//OpenPKG//DTD OpenPKG Registry 0.0.1//EN\""
            echo "  \"http://registry.openpkg.org/registry.dtd\" []>"
            echo "<registry>"
            echo "    <response id=\"$request\" done=\"yes\">fake</response>"
            echo "</registry>"
        ) | tee $REGISTRY_TRAN
    fi

    if [ ".$REGISTRY_MODE" = .post ]; then
        O=""
        if [ $verbose = no ]; then O="$O --silent"; fi
        $curl \
            $O \
            --user-agent "$useragent" \
            --connect-timeout 15 \
            --max-time 120 \
            --form 'page=dropxml' \
            --form 'data=<-' \
            --form 'submit=DROPXML' \
            $REGISTRY_ARGS \
        | tee $REGISTRY_TRAN
    fi
}

##
##  Primary operation Utilization
##
utilization()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        if [ ".$REGISTRY_UTIL" != . ]; then
            if [ -f $REGISTRY_UTIL ]; then
                cat </dev/null >$REGISTRY_UTIL
            fi
        fi
        return
    fi

    [ ".$REGISTRY_UTIL" = . ] && error "missing information REGISTRY_UTIL"

    response=`awk '
        BEGIN { registry=0 }
        /<registry>/ { registry=1 }
        /<response / { if (registry) { print $0 } }
        /<\/registry>/ { registry=0 }' | \
        sed -e 's;^.*<response id=";;' -e 's;" done="; ;' -e 's;">; ;' -e 's;</response>.*$;;'`
    if [ ".$response" = . ]; then error "no response seen on stdin"; fi

    REGISTRY_DBID=`echo $response | awk '/./ { print $1 }'`
    REGISTRY_DONE=`echo $response | awk '/./ { print $2 }'`
    REGISTRY_RESP=`echo $response | sed -e 's;^[^ ][^ ]* [^ ][^ ]* ;;'`

    [ ".$REGISTRY_DBID" = . ] && error "missing information REGISTRY_DBID"
    [ ".$REGISTRY_DONE" = . ] && error "missing information REGISTRY_DONE"
    [ ".$REGISTRY_RESP" = . ] && error "missing information REGISTRY_RESP"

    (
        echo "REGISTRY_DBID=\"$REGISTRY_DBID\""
        echo "REGISTRY_DONE=\"$REGISTRY_DONE\""
        echo "REGISTRY_RESP=\"$REGISTRY_RESP\""
    ) | tee $REGISTRY_UTIL
}

##
##  Automatic registration data retrieval
##
autoregdata()
{
    if [ ".$REGISTRY_AUTO" != . ]; then
        O=""
        if [ $verbose = no ]; then O="$O --silent"; fi
        response=`$curl \
            $O -L \
            --user-agent "$useragent" \
            --connect-timeout 8 \
            --max-time 16 \
            $REGISTRY_AUTO \
        | awk '
            BEGIN { registry=0 }
            /<registry>/ { registry=1 }
            /<autoregister / { if (registry) { print $0 } }
            /<\/registry>/ { registry=0 }' \
        | sed -e 's;^.*<autoregister *;;' -e 's;>[^>]*</autoregister>.*$;;' \
          -e 's;\([^=]*\)="\([^"]*\)" *;\1="\2"\\
;g' \
        | awk -F= '/=/ { print "REGISTRY_"toupper($1)"="$2"" }'`
        if [ $verbose = yes ]; then echo "autoregdata from $REGISTRY_AUTO"; echo "$response"; fi
        eval "$response"
    fi
}

##
##  Primary operation Convenience
##
convenience()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        utilization
        transaction
        preparation
        return
    fi

    preparation | transaction | utilization

    readutil || error "problem reading util"
    if [ ".$REGISTRY_DONE" = .yes ]; then
        echo "#`TZ= date '+%Y-%m-%d %H:%M:%S'` UTC" | tee "$REGISTRY_CONF" || return
        (
            echo "REGISTRY_USER=\"$REGISTRY_USER\""
            echo "REGISTRY_LINK=\"$REGISTRY_LINK\""
            echo "REGISTRY_DESC=\"$REGISTRY_DESC\""
            echo "REGISTRY_PLAT=\"$REGISTRY_PLAT\""
            echo "REGISTRY_OREL=\"$REGISTRY_OREL\""
            echo "REGISTRY_UUID=\"$REGISTRY_UUID\""
            echo "REGISTRY_PREP=\"$REGISTRY_PREP\""
            echo "REGISTRY_MODE=\"$REGISTRY_MODE\""
            echo "REGISTRY_ARGS=\"$REGISTRY_ARGS\""
            echo "REGISTRY_TRAN=\"$REGISTRY_TRAN\""
            echo "REGISTRY_UTIL=\"$REGISTRY_UTIL\""
        ) | tee -a "$REGISTRY_CONF"
    fi
}

##
##  Primary operation Interaction
##
interaction()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        if [ ".$REGISTRY_CONF" != . ]; then
            if [ -f $REGISTRY_CONF ]; then
                cat </dev/null >$REGISTRY_CONF
            fi
        fi
        return
    fi

    echo "OpenPKG Registry Client ($useragent)"
    echo ""
    echo "Interactive step-by-step registration procedure."
    echo "You can abort at any time by just pressing CTRL-C."
    echo ""
    echo "Registration is a three step process:"
    echo "1. Preparation = create a configuration file and locally prepare a registration request"
    echo "2. Transaction = run a transaction to submit the request to the registry"
    echo "3. Utilization = memorize the response to activate local URL rewriting"
    echo ""
    echo "A (*) marks an optional field where the empty string \"\" is allowed."
    echo "Just press RETURN to continue and/or keep a default setting."

    echo ""
    echo "==== Step 1/3: Preparation ===="
    echo "Attempting to write to the configuration file \"$REGISTRY_CONF\""
    echo "#`TZ= date '+%Y-%m-%d %H:%M:%S'` UTC" | tee -a "$REGISTRY_CONF" 2>/dev/null \
        || error "Configuration file not writable. Get more permissions and try again"

    read -p "[REGISTRY_USER=\"$REGISTRY_USER\"] username? ";          [ ".$REPLY" != . ] && REGISTRY_USER="$REPLY"
    read -p "[REGISTRY_DESC=\"$REGISTRY_DESC\"] description (*)? ";   [ ".$REPLY" != . ] && REGISTRY_DESC="$REPLY"
    read -p "[REGISTRY_PLAT=\"$REGISTRY_PLAT\"] platform (*)? ";      [ ".$REPLY" != . ] && REGISTRY_DESC="$REPLY"
    read -p "[REGISTRY_OREL=\"$REGISTRY_OREL\"] release (*)? ";       [ ".$REPLY" != . ] && REGISTRY_DESC="$REPLY"
    read -p "[REGISTRY_UUID=\"$REGISTRY_UUID\"] uuid file to read? "; [ ".$REPLY" != . ] && REGISTRY_UUID="$REPLY"
    read -p "[REGISTRY_DATA=\"$REGISTRY_DATA\"] data to prepare? ";   [ ".$REPLY" != . ] && REGISTRY_DATA="$REPLY"
    read -p "[REGISTRY_PREP=\"$REGISTRY_PREP\"] prep dump file? ";    [ ".$REPLY" != . ] && REGISTRY_PREP="$REPLY"

    [ ".$REGISTRY_USER" = . ] && error "missing information REGISTRY_USER"
    [ ".$REGISTRY_DESC" = . ] && error "missing information REGISTRY_DESC"
    [ ".$REGISTRY_PLAT" = . ] && error "missing information REGISTRY_PLAT"
    [ ".$REGISTRY_OREL" = . ] && error "missing information REGISTRY_OREL"
    [ ".$REGISTRY_UUID" = . ] && error "missing information REGISTRY_UUID"
    [ ".$REGISTRY_DATA" = . ] && error "missing information REGISTRY_DATA"
    [ ".$REGISTRY_PREP" = . ] && error "missing information REGISTRY_PREP"

    if [ -r "$REGISTRY_UUID" ]; then
        sanitycheck "$REGISTRY_UUID" && . "$REGISTRY_UUID"
    fi
    [ ".$UUID_REGISTRY" = . ] && error "missing information UUID_REGISTRY"
    [ ".$UUID_INSTANCE" = . ] && error "missing information UUID_INSTANCE"
    [ ".$UUID_PLATFORM" = . ] && error "missing information UUID_PLATFORM"

    echo "Appending to configuration file \"$REGISTRY_CONF\""
    (
        echo "REGISTRY_USER=\"$REGISTRY_USER\""
        echo "REGISTRY_LINK=\"$REGISTRY_LINK\""
        echo "REGISTRY_DESC=\"$REGISTRY_DESC\""
        echo "REGISTRY_PLAT=\"$REGISTRY_PLAT\""
        echo "REGISTRY_OREL=\"$REGISTRY_OREL\""
        echo "REGISTRY_UUID=\"$REGISTRY_UUID\""
        echo "REGISTRY_PREP=\"$REGISTRY_PREP\""
    ) | tee -a "$REGISTRY_CONF"

    preparation

    echo ""
    echo "==== Step 2/3: Transaction ===="
    read -p "[REGISTRY_MODE=\"$REGISTRY_MODE\"] mode (post or fake)? "; [ ".$REPLY" != . ] && REGISTRY_MODE="$REPLY"
    read -p "[REGISTRY_ARGS=\"$REGISTRY_ARGS\"] args? ";                [ ".$REPLY" != . ] && REGISTRY_ARGS="$REPLY"
    read -p "[REGISTRY_TRAN=\"$REGISTRY_TRAN\"] tran dump file? ";      [ ".$REPLY" != . ] && REGISTRY_TRAN="$REPLY"

    [ ".$REGISTRY_MODE" = . ] && error "missing information REGISTRY_MODE"
    [ ".$REGISTRY_ARGS" = . ] && error "missing information REGISTRY_ARGS"
    [ ".$REGISTRY_TRAN" = . ] && error "missing information REGISTRY_TRAN"

    echo "Appending to configuration file \"$REGISTRY_CONF\""
    (
        echo "REGISTRY_MODE=\"$REGISTRY_MODE\""
        echo "REGISTRY_ARGS=\"$REGISTRY_ARGS\""
        echo "REGISTRY_TRAN=\"$REGISTRY_TRAN\""
    ) | tee -a "$REGISTRY_CONF"

    transaction <$REGISTRY_PREP

    echo ""
    echo "==== Step 3/3: Utilization ===="
    read -p "[REGISTRY_UTIL=\"$REGISTRY_UTIL\"] util dump file? ";      [ ".$REPLY" != . ] && REGISTRY_UTIL="$REPLY"

    [ ".$REGISTRY_UTIL" = . ] && error "missing information REGISTRY_UTIL"

    echo "Appending to configuration file \"$REGISTRY_CONF\""
    (
        echo "REGISTRY_UTIL=\"$REGISTRY_UTIL\""
    ) | tee -a "$REGISTRY_CONF"

    utilization <$REGISTRY_TRAN
}

##
##  Additional feature printstatus
##
printstatus()
{
    rc=0
    readconf || error "problem reading conf"
    readuuid || error "problem reading uuid"
    readutil || error "problem reading util"
    if [ ".$REGISTRY_DONE" = .yes ]; then
        cat "$REGISTRY_UTIL"
        return 0
    fi
    return 1
}

##
##  Additional feature rewriteurls
##
rewriteurls()
{
    readconf && readuuid && readutil || return $?
    if [ ".$REGISTRY_DONE" = .yes ]; then
        #   URL rewriting
        while [ ".$1" != . ]; do
            printf '%s\n' "$1" | \
            sed -e "s;^\([^:/]*\)://\([^:/]*\.openpkg\.com\)/;\1://$UUID_REGISTRY:$UUID_INSTANCE.$UUID_PLATFORM@\2/;" \
                -e "s;^\([^:/]*\)://\([^:/]*\.openpkg\.org\)/;\1://$UUID_REGISTRY:$UUID_INSTANCE.$UUID_PLATFORM@\2/;" \
                -e "s;^\([^:/]*\)://\([^:/]*\.openpkg\.net\)/;\1://$UUID_REGISTRY:$UUID_INSTANCE.$UUID_PLATFORM@\2/;"
            shift
        done
        return 0
    else
        #   stealth mode
        return 1
    fi
}

##
##  check whether important configuration data is missing
##
checkmissing()
{
    missing=""
    [ ".$REGISTRY_USER" = . ] && missing="$missing REGISTRY_USER"
    [ ".$REGISTRY_DESC" = . ] && missing="$missing REGISTRY_DESC"
    [ ".$REGISTRY_PLAT" = . ] && missing="$missing REGISTRY_PLAT"
    [ ".$REGISTRY_OREL" = . ] && missing="$missing REGISTRY_OREL"
    [ ".$REGISTRY_UUID" = . ] && missing="$missing REGISTRY_UUID"
    [ ".$REGISTRY_PREP" = . ] && missing="$missing REGISTRY_PREP"
    [ ".$REGISTRY_MODE" = . ] && missing="$missing REGISTRY_MODE"
    [ ".$REGISTRY_ARGS" = . ] && missing="$missing REGISTRY_ARGS"
    [ ".$REGISTRY_TRAN" = . ] && missing="$missing REGISTRY_TRAN"
    [ ".$REGISTRY_UTIL" = . ] && missing="$missing REGISTRY_UTIL"
}

##
##  automatically pick interaction or convenience
##
automatic()
{
    if [ ".$REGISTRY_MODE" = .wipe ]; then
        convenience
        interaction
        return
    fi

    checkmissing
    if [ ".$missing" != . ]; then
        autoregdata
    fi

    checkmissing
    if [ ".$missing" = . ]; then
        convenience
    else
        tty -s || return
        echo "missing $missing"
        interaction
    fi
}

##
##  primary operation switch
##
eval $op "\"$@\""
exit $?

##
##  MANUAL PAGE
##

