#!/bin/sh
#
# $Id$
#
# Copyright 2019-2020, Juniper Networks, Inc
# All Rights Reserved
#

VERIEXEC=/sbin/veriexec

if ! type is_verified > /dev/null 2>&1; then
    # we'll override this below if appropriate
    is_verified() { return 0; }

    if test -s $VERIEXEC; then
        if $VERIEXEC -i active > /dev/null 2>&1; then
            is_verified() { $VERIEXEC -x $1; }
        fi
    fi
fi

# avoid multiple inclusion and duplicate effort
_VDOT_SH=:

# in case we want to avoid repeats
dotted=
# try not to include things we cannot verify
vdot() {
    local f rc=0

    for f in "$@"
    do
        test -s $f || continue
        if is_verified $f 2> /dev/null; then
            dotted="$dotted $f"
            . $f
        else
            rc=80               # EAUTH
        fi
    done
    return $rc
}

vdot_once() {
    local f rc=0

    for f in "$@"
    do
        case " $dotted " in
        *" $f "*) continue;;
        esac
        vdot $f || rc=$?
    done
    return $rc
}

# for unverified things
dot() {
    local f

    for f in "$@"
    do
        if test -s $f; then
            dotted="$dotted $f"
            . $f
        fi
    done
}

dot_once() {
    local f

    for f in "$@"
    do
        case " $dotted " in
        *" $f "*) continue;;
        esac
        dot $f
    done
}

# unit test
case "/$0" in
*/vdot*) vdot "$@";;
esac
#!/bin/sh

# comment next line to enable testing
_DEBUG_OSP=:

# facilitate testing
PKGROOT=${PKGROOT:-/packages}
PKGSETS=${PKGSETS:-$PKGROOT/sets}
PKGSMNT=${PKGSMNT:-$PKGROOT/mnt}
PKGTOOLS=${PKGTOOLS:-/usr/libexec}

# if this is missing os-runtime cannot be newer
if test -s $PKGTOOLS/pkg_funcs.sh; then
    old_os=:
    have_funcs=
else
    old_os=
    have_funcs=:
fi

# check if this package is "too old" and warn
is_too_old() {
    check_utc=1678239504
    # are we doing unit-tests?
    case "$PKG_BOOTSTRAP,$OS_PACKAGE_BUILD_UTC" in
    tests,[1-9]*) check_utc=$OS_PACKAGE_BUILD_UTC;;
    esac
    # warn if we are more than too_old days old
    too_old=${OS_PACKAGE_TOO_OLD:-180}
    utc=`date +%s`
    ok=$((utc - ( $too_old * 86400 )))
    test ${check_utc:-$ok} -ge $ok ||
	echo "WARNING: ${PKG_NAME:-${PKGDIR##*/}} is more than $too_old days old"
}

is_active_safe() {
    $old_os return 1
    get_xmltags $PKGSETS/$PKGSET/os-kernel/package.xml "pkg-feature-.*"
    test -n "$pkg_feature_ospackagesafe"
}

is_runtime_newer() {
    $old_os return 1
    get_xmltags $PKGSETS/$PKGSET/os-runtime/package.xml package-utc
    osr_utc=${package_utc:-0}
    get_xmltags $PKGDIR/package.xml package-utc
    case "$PKG_COMMAND,$action" in
    add,activate) is_too_old;;
    esac
    test ${package_utc:-1} -le $osr_utc
}

# why we self-deactivate
reason=required

need_deactivate() {
    : PKG_COMMAND=$PKG_COMMAND
    case "$PKG_COMMAND" in
    mount$_DEBUG_OSP) # this helps us test
        ${SKIP_PREBOOT_MOUNT:-:} 1
        ;;
    setop|start)
        boot_set=`kenv -q boot_set`
        case "$boot_set,$PKGSET" in
        active,active)
            if test ! -s $PKGSMNT/$PKG_BASENAME/pkg/manifest; then
                # we should not be here - but we are
                reason=safe
                return 0
            fi
            ;;
        pending,active)
            # if we are being activated from pending set
            # we should already be mounted by preboot
            # otherwise it is not safe for us to remain
            if test ! -s $PKGSMNT/$PKG_BASENAME/pkg/manifest; then
                reason=safe
                return 0
            fi
            ;;
        esac
        ;;
    esac
    # if os-runtime is newer we should go away
    is_runtime_newer
}

# our logic is much simpler if we are a bundled package
is_bundled() {
    $old_os return 1
    test tests = "$PKG_BOOTSTRAP" && return 1
    test -s $PKGSMNT/os-runtime/usr/libexec/pkg_add.sh || return 0
    grep -q 'package name="os-package' $PKGSETS/$PKGSET/packages.xml $PKGSETS/active/packages.xml 2> /dev/null
}

vdot $PKGDIR/scripts/pkg_funcs.sh
$_DEBUG_OSP dot /.mount/etc/debug.os-package

DebugOn bundled
if is_bundled; then
    # this is very simple
    : action=$1
    case "$1" in
    deactivat*|delet*)
        : PKGSET,PKG_COMMAND=$PKGSET,$PKG_COMMAND
        case "$PKGSET,$PKG_COMMAND" in
        active,deactivat*|active,delet*)
            # check if $PKGDIR is actually a member
            if is_active $PKGDIR; then
                echo "ERROR: $PKG_BASENAME cannot be removed from 'active' set."
                exit 2
            fi
            ;;
        esac
        ;;
    activate|mount*)
        make_symlink /packages/mnt/os-package/etc/rc.d/mount /etc/rc.d/mount
        rm_symlink /packages/mnt/os-package/usr/libexec/ui/package-info.d/os-package.sh /usr/libexec/ui/package-info.d/os-package.sh
        ;;
    esac
    exit 0
fi
DebugOff bundled

# we get run for several actions
action=$1
case "$1" in
delet*|deactiv*) ;;
*)
    DebugOn active_safe
    if is_active_safe; then
        case "$1" in
        activate|mount*)
            make_symlink /packages/mnt/os-package/etc/rc.d/mount /etc/rc.d/mount
            ;;
        esac
    else
        case "$1" in
        activate)
            # guard against a reboot with us in active set!
            rm -f /packages/mnt/os-runtime.last
            echo "WARNING: do NOT reboot with $PKG_BASENAME in 'active' set!"
            ;;
        esac
    fi
    make_symlink /packages/mnt/os-package/usr/libexec/ui/package-info.d/os-package.sh /usr/libexec/ui/package-info.d/os-package.sh
    DebugOff active_safe
    DebugOn need_deactivate
    need_deactivate || exit 0
    DebugOff need_deactivate
    ;;
esac

restore_symlinks() {
    {
        echo /packages/mnt/os-runtime/etc/rc.d/mount /etc/rc.d/mount
        sed "s,$PKG_BASENAME,os-runtime," $PKGDIR/contents/contents.symlinks
    } | make_symlinks
}

self_deactivate() {
    echo "Removing ${PKGDIR##*/} from $PKGSET: no longer $reason"
    DebugOn self_deactivate
    rm -f $PKGSETS/$PKGSET/$PKG_BASENAME
    # repair symlinks
}

rc=0

case "$1" in
delet*|deactiv*) ;;
activate|mounting) rc=1; self_deactivate;;
*) self_deactivate;;
esac
$have_funcs restore_symlinks
exit $rc
