#!/bin/sh

# $Id: mount_iso.sh 728879 2015-08-07 23:11:50Z toddtop $

for p in /packages/mnt/jbase /junos ""
do
    VERIEXEC=$p/sbin/veriexec
    test -x $VERIEXEC && break
done

# return the first of $* that exists
Exists() {
    case "$1" in
    -?) _t=$1; shift;;
    *) _t=-s;;
    esac
    for f in $*
    do 
	[ $_t $f ] || continue
	echo $f
	break
    done
}

force=

while :
do
    case $1 in
    --force) $NO_FORCE_MOUNT eval force=:; shift;;
    *) break;;
    esac
done

pkgpath=$1
mntpoint=$2
package=$3
pkg=${pkgpath##*/}

#
# SHA1 is much better than MD5, use it if available
#
for hash in sha1 md5
do
    [ -s /sbin/$hash ] || continue
    [ -s $pkgpath.$hash ] || continue

    want=`cat $pkgpath.$hash`
    have=`/sbin/$hash < $pkgpath`
    if [ "x${have}" != "x${want}" ]; then
	logger -t mount_check -s -p daemon.alert "`$hash $pkgpath` != $want"
	$force exit 65		# EX_DATAERR
    fi
    break
done

# make sure we can mount it
[ -d $mntpoint ] || (umask 022; mkdir -p $mntpoint)

mdd=`mdconfig -a -t vnode -o jcompress -o readonly -JO -f $pkgpath`
if [ -z $mdd ]; then
    echo "Unable to mount $package - no more md devices"
    exit 1
fi

#
# external packages on RE are mounted with specific user/group-ids
#
pkg_provider_id=
pkg_jnx_options=
pkg_is_on_pic=`sysctl -n hw.pic.hw_revision 2>/dev/null`
if [ -z "$pkg_is_on_pic" -a -x /sbin/x509-exts ]; then
    # we're on RE ... temporarily mount as 'nobody' to get the provider-id
    if mount -t cd9660 -Ju 65534 -Jg 65534 -r -onoexec /dev/$mdd $mntpoint; then

	# get the provider-id
	pkg_certs=`Exists $mntpoint/pkg/manifest.certs $mntpoint/pkg/certs.pem`
	if [ "$pkg_certs" ]; then
	    pkg_provider_id=`x509-exts -x "jnxProviderId" $pkg_certs` 
	    pkg_prov_name=`x509-exts -x "jnxProviderName" $pkg_certs`
	fi
	umount $mntpoint

	# external users have provider-ids >= 0x8000
	if expr ${pkg_provider_id:-0} '>=' 0x8000 >/dev/null 2>&1; then
	    # it is external ... mount package as 'ext'
	    if [ "$pkg_prov_name" ]; then
		mkdir -p -m 775 /var/run/ext/$pkg_prov_name \
		    /var/log/ext/$pkg_prov_name \
		    /var/db/ext/$pkg_prov_name
		chown ${pkg_jnx_uid:-39}:39 /var/run/ext/$pkg_prov_name \
		    /var/log/ext/$pkg_prov_name \
		    /var/db/ext/$pkg_prov_name
	    fi
	    pkg_jnx_uid=`ext_id_map -a -p ${pkg_provider_id} 2>/dev/null`
	    pkg_jnx_options="-Ju ${pkg_jnx_uid:-39} -Jg 39"
	fi
    else
	echo Unable to mount $package on /dev/$mdd
	mdconfig -d -u ${mdd##*md}
	exit 1
    fi
fi

if mount -t cd9660 $pkg_jnx_options -r /dev/$mdd $mntpoint; then
    echo "Mounted $package package on /dev/$mdd..."
    # load fingerprints if present
    if [ -x $VERIEXEC -a -s $mntpoint/pkg/manifest ]; then
	$VERIEXEC -C $mntpoint $mntpoint/pkg/manifest
	if [ -s $pkgpath.esig -a -s $pkgpath.ecerts ]; then
	    # bless the iso if we can - saves a lot of overhead
	    $VERIEXEC -b $pkgpath
	elif [ -s $pkgpath.sig -a -s $pkgpath.certs ]; then
	    # bless the iso if we can - saves a lot of overhead
	    $VERIEXEC -b $pkgpath
        fi
    fi
    # look to see if this package has a special mount procedure
    postmount=$mntpoint/mount.post

    if [ -f $postmount ]; then
	echo "Executing $postmount.."
	$postmount $mntpoint
	x=$?		# just so it shows up
	case $x in
	0)  ;;		# all ok
	1)  exit 1;;	# failed but carry on
	*)  echo "Unmounting $mntpoint..."
	    umount $mntpoint &&
	    mdconfig -d -u ${mdd##*md}
	    exit $x
	    ;;
	esac
    fi
    exit 0
else
    echo Unable to mount $package on /dev/$mdd
    mdconfig -d -u ${mdd##*md}
    exit 1
fi
