#!/bin/sh -e

##########################################################################
#   Script description:
#       Quickly bootstrap a pkgsrc installation utilizing binary
#       packages provided by Joyent Cloud Services.
#
#   History:
#   Date        Name        Modification
#   2017-08-09  Jason Bacon Begin
##########################################################################

usage()
{
    printf "Usage: $0 \n"
    exit 1
}


##########################################################################
#   Function description:
#       Pause until user presses return
##########################################################################

pause()
{
    printf "Press return to continue..."
    read junk
}


##########################################################################
#   Main
##########################################################################

if [ $# != 0 ]; then
    usage
fi

if [ $(whoami) != root ]; then
    printf "$0 must be run as root.  Use \"su\" or \"sudo\".\n"
    exit 1
fi

os=`uname`
case $os in
Darwin)
    PREFIX=/opt/pkg
    PKGSRC=/opt/pkgsrc
    ;;

Linux)
    PREFIX=/usr/pkg
    PKGSRC=/usr/pkgsrc
    ;;

SunOS)
    PREFIX=/opt/local
    PKGSRC=/opt/pkgsrc
    ;;

*)
    ;;

esac

if [ ! -e $PREFIX/bin/sbmake ]; then
    os=`uname`
    case $os in
    Darwin)
	# Install Xcode Command Line Tools if necessary
	if [ ! -e /Library/Developer/CommandLineTools ]; then
	    xcode-select --install
	fi
	os=$(uname)$(uname -r | cut -d . -f 1)
	case $os in
	Darwin17)
	    BOOTSTRAP_TAR="bootstrap-trunk-x86_64-20190524.tar.gz"
	    BOOTSTRAP_SHA="1c554a806fb41dcc382ef33e64841ace13988479"
	    site="https://us-east.manta.joyent.com/pkgsrc/public/packages/Darwin/10.12/bootstrap"
	    ;;
	    
	Darwin18)
	    BOOTSTRAP_TAR="bootstrap-macos14-trunk-x86_64-20200716.tar.gz"
	    BOOTSTRAP_SHA="395be93bf6b3ca5fbe8f0b248f1f33181b8225fe"
	    site="https://pkgsrc.joyent.com/packages/Darwin/bootstrap"
	    ;;
	
	Darwin20)
	    BOOTSTRAP_TAR="bootstrap-macos11-trunk-x86_64-20201112.tar.gz"
	    BOOTSTRAP_SHA="b3c0c4286a2770bf5e3caeaf3fb747cb9f1bc93c"
	    site="https://pkgsrc.joyent.com/packages/Darwin/bootstrap"
	    ;;
	
	*)
	    printf "$0: Not supported on $os.\n"
	    exit 1
	    ;;
	
	esac
	sha_cmd=shasum
	;;
    
    Linux)
	if [ -e /etc/redhat-release ]; then
	    if [ `awk '{ print $2 }' /etc/redhat-release` = release ]; then
		major=`awk '{ print $3 }' /etc/redhat-release | awk -F . '{ print $1 }'`
	    else
		major=`awk '{ print $4 }' /etc/redhat-release | awk -F . '{ print $1 }'`
	    fi
	    case $major in
	    7)
		BOOTSTRAP_TAR="bootstrap-el7-trunk-x86_64-20200724.tar.gz"
		BOOTSTRAP_SHA="478d2e30f150712a851f8f4bcff7f60026f65c9e"
		site="https://pkgsrc.joyent.com/packages/Linux/el7/bootstrap"
		release=el7
		;;
	    *)
		printf "Unsupported RHEL release: $major\n"
		exit 1
		;;
	    esac
	else
	    printf "Only RHEL Linux distributions are supported at this time.\n"
	    exit 1
	fi
	sha_cmd=sha1sum
	;;
    
    SunOS)
	BOOTSTRAP_TAR="bootstrap-trunk-x86_64-20201019.tar.gz"
	BOOTSTRAP_SHA="127d6a561d6ae4ce07cdb87e3dd185b837f6cc18"
	site="https://pkgsrc.joyent.com/packages/SmartOS/bootstrap"
	sha_cmd=sha1sum
	;;

    *)
	printf "$0: Not supported on $(auto-ostype).\n"
	exit 1
	;;
    
    esac
    
    # Download the bootstrap kit to the current directory.
    if [ ! -e $BOOTSTRAP_TAR ];then
	curl --insecure -O $site/$BOOTSTRAP_TAR
    fi
    
    # Verify the SHA1 checksum.
    echo "${BOOTSTRAP_SHA}  ${BOOTSTRAP_TAR}" > check-shasum
    $sha_cmd -c check-shasum
    
    cat << EOM

Attempting to verify PGP signature of the bootstrap tarball.
You may wish to verify the signature

    $BOOTSTRAP_SHA

from the latest information at

    https://pkgsrc.joyent.com/

EOM

    # Verify PGP signature.  This step is optional, and requires gpg.
    if which gpg; then
	curl --insecure -O https://pkgsrc.joyent.com/packages/$os/$release/bootstrap/${BOOTSTRAP_TAR}.asc
	curl --insecure -sS https://pkgsrc.joyent.com/pgp/56AAACAF.asc | gpg --import
	gpg --verify ${BOOTSTRAP_TAR}{.asc,}
	printf "Tarball matches $BOOTSTRAP_SHA\n"
    else
	printf "No GPG command found.  Please install gnupg and verify manually.\n"
    fi
    pause

    # Install bootstrap kit to $PREFIX
    printf "Unpacking...\n"
    tar -zxpf ${BOOTSTRAP_TAR} -C /
fi

# Add paths
export PATH=$PREFIX/sbin:$PREFIX/bin:$PATH
export MANPATH=$PREFIX/man:$MANPATH

pkgin -y full-upgrade || true
pkgin -y install digest || true

cd $PREFIX/..
if [ ! -e pkgsrc ]; then
    pkgin -y install cvs || true
    printf "Checking out source tree.  This may take a few minutes...\n"
    # cvs -Q -danoncvs@anoncvs.netbsd.org:/cvsroot checkout pkgsrc
    curl --insecure -O https://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc.tar.xz
    printf "Unpacking...\n"
    tar Jxf pkgsrc.tar.xz
    CVS_RSH=ssh
    export CVS_RSH
    cd pkgsrc
    cvs -q up -dP
    cd ..
    rm -f pkgsrc.tar.xz
fi

cd pkgsrc
if [ ! -e wip ]; then
    printf "Install pkgsrc-wip? [y]/n "
    read wip
    if [ 0$wip != 0n ]; then
	pkgin -y install git || true
	git clone git://wip.pkgsrc.org/pkgsrc-wip.git wip
    fi
fi

conf="$PREFIX/etc/pkg_install.conf"
sed -e 's|VERIFIED_INSTALLATION=always|VERIFIED_INSTALLATION=trusted|g' \
    $conf > $conf.tmp
mv -f $conf.tmp $conf

cat << EOM

To build your own packages from source without being prompted about
PGP signatures, either set

VERIFIED_INSTALLATION=never

in $PREFIX/etc/pkg_install.conf (this will reduce security), or sign your
packages with PGP:

Enable SIGN_PACKAGES in $PREFIX/etc/mk.conf:

    SIGN_PACKAGES=  gpg

Install GPG, create a signing key, and then configure 
$PREFIX/etc/pkg_install.conf with:

    GPG=/path/to/gpg
    GPG_SIGN_AS=your_pgp_key_id

For details, see:

http://www.perkin.org.uk/posts/pkgsrc-2014Q4-lts-signed-packages-and-more.html
EOM

# Wrap bmake command
cat << EOM2 > $PREFIX/bin/sbmake
#!/bin/sh -e

if ! pwd | fgrep -q $PKGSRC; then
    cat << EOM
    
			    ===== Error =====

You are running \$(which bmake) from the wrong directory.
It should only be used from within $PKGSRC.
Load the correct environment module or source the correct startup script
so that you are using the appropriate bmake for \$(pwd),
or cd to $PKGSRC to use \$(which bmake).

EOM
    exit 1
fi

# Make sure software installed is world-readable on systems with tighter
# default umask.
umask 022
bmake \$@
EOM2
chmod 755 $PREFIX/bin/sbmake

cat << EOM > $PREFIX/etc/pkgsrc.sh
# Generated by joyent-pkgsrc
if ! echo \$PATH | fgrep -q "${PREFIX}/bin:"; then
    PKGSRC=$PREFIX
    export PKGSRC
    
    # Scrub PATH and LD_LIBRARY_PATH before adding pkgsrc to prevent leakage
    # CentOS 7 /bin/gcc fails with cannot find cc1, so put /usr/bin first
    PATH=/usr/bin:/usr/sbin:/bin:/sbin
    unset CC CFLAGS CXX CXXFLAGS CPP CPPFLAGS FC FFLAGS LD LDFLAGS LD_LIBRARY_PATH
    
    PATH=\$PKGSRC/bin:\$PKGSRC/sbin:\$PATH
    export PATH
    MANPATH=\$PKGSRC/man:/usr/share/man
    export MANPATH
    PKGSRC_INCLUDE=\$PKGSRC/include
    export PKGSRC_INCLUDE
    PKGSRC_LIB=\$PKGSRC/lib
    export PKGSRC_LIB
fi
EOM

cat << EOM > $PREFIX/etc/pkgsrc-non-exclusive.sh
# Generated by joyent-pkgsrc
if ! echo \$PATH | fgrep -q "${PREFIX}/bin:"; then
    PKGSRC=$PREFIX
    export PKGSRC
    
    PATH=\$PKGSRC/bin:\$PKGSRC/sbin:\$PATH
    export PATH
    MANPATH=\$PKGSRC/man:/usr/share/man
    export MANPATH
    PKGSRC_INCLUDE=\$PKGSRC/include
    export PKGSRC_INCLUDE
    PKGSRC_LIB=\$PKGSRC/lib
    export PKGSRC_LIB
fi
cat << EOW

==============================================================================
WARNING:

pkgsrc-non-exclusive.sh allows programs and libraries that are not part of
this pkgsrc tree or the base system to remain in PATH and LD_LIBRARY_PATH.
This may cause some programs to malfunction.
==============================================================================

EOW
EOM

cat << EOM > $PREFIX/etc/pkgsrc.csh
# Generated by joyent-pkgsrc
echo \$PATH | fgrep -q "${PREFIX}/bin:"
if ( \$status != 0 ) then
    setenv PKGSRC           $PREFIX
    
    # Scrub PATH and LD_LIBRARY_PATH before adding pkgsrc to prevent leakage
    # CentOS 7 /bin/gcc fails with cannot find cc1, so put /usr/bin first
    setenv PATH             /usr/bin:/usr/sbin:/bin:/sbin
    unsetenv CC CFLAGS CXX CXXFLAGS CPP CPPFLAGS FC FFLAGS LD LDFLAGS LD_LIBRARY_PATH

    setenv PATH             \$PKGSRC/bin:\$PKGSRC/sbin:\$PATH
    setenv MANPATH          \$PKGSRC/man:/usr/share/man
    setenv PKGSRC_INCLUDE   \$PKGSRC/include
    setenv PKGSRC_LIB       \$PKGSRC/lib
endif
EOM

cat << EOM > $PREFIX/etc/pkgsrc-non-exclusive.csh
# Generated by joyent-pkgsrc
echo \$PATH | fgrep -q "${PREFIX}/bin:"
if ( \$status != 0 ) then
    setenv PKGSRC           $PREFIX
    
    setenv PATH             \$PKGSRC/bin:\$PKGSRC/sbin:\$PATH
    setenv MANPATH          \$PKGSRC/man:/usr/share/man
    setenv PKGSRC_INCLUDE   \$PKGSRC/include
    setenv PKGSRC_LIB       \$PKGSRC/lib
endif
cat << EOW

==============================================================================
WARNING:

pkgsrc-non-exclusive.csh allows programs and libraries that are not part of
this pkgsrc tree or the base system to remain in PATH and LD_LIBRARY_PATH.
This may cause some programs to malfunction.
==============================================================================

EOW
EOM

mkdir -p $PREFIX/etc/modulefiles/pkgsrc
cat << EOM > $PREFIX/etc/modulefiles/pkgsrc/current

#%Module1.0#####################################################################
proc ModulesHelp { } {
    puts stdout "\n\tAll software installed via the pkgsrc package management"
    puts stdout "\tsystem. This module prepends the pkgsrc directories to"
    puts stdout "\tappropriate environment variable(s)."
}

module-whatis   "All software installed via pkgsrc"

set     version         current
set     install_prefix  $PREFIX

# Scrub PATH before adding pkgsrc to prevent leakage during builds
setenv  PATH    /usr/bin:/usr/sbin:/bin:/sbin
unsetenv        CC
unsetenv        CFLAGS
unsetenv        CXX
unsetenv        CXXFLAGS
unsetenv        CPP
unsetenv        CPPFLAGS
unsetenv        FC
unsetenv        FFLAGS
unsetenv        LD
unsetenv        LDFLAGS
unsetenv        LD_LIBRARY_PATH

prepend-path    PATH    $install_prefix/bin:$install_prefix/sbin
prepend-path    MANPATH         $install_prefix/man:/usr/share/man
prepend-path    MODULEPATH      $install_prefix/etc/modulefiles

setenv          PKGSRC          $install_prefix
setenv          PKGSRC_INCLUDE  $install_prefix/include
setenv          PKGSRC_LIB      $install_prefix/lib
EOM

cat << EOM > $PREFIX/etc/modulefiles/pkgsrc/current-non-exclusive

#%Module1.0#####################################################################
proc ModulesHelp { } {
    puts stdout "\n\tAll software installed via the pkgsrc package management"
    puts stdout "\tsystem. This module prepends the pkgsrc directories to"
    puts stdout "\tappropriate environment variable(s)."
}

module-whatis   "All software installed via pkgsrc"

puts stderr "\n======================================================================"
puts stderr "WARNING:\n"
puts stderr "pkgsrc/current-non-exclusive allows programs and libraries"
puts stderr "that are not part of this pkgsrc tree or the base system to remain in"
puts stderr "PATH and LD_LIBRARY_PATH.  This may cause some programs to malfunction."
puts stderr "======================================================================\n"

set     version         current
set     install_prefix  $PREFIX

# Scrub PATH before adding pkgsrc to prevent leakage during builds
setenv  PATH    /usr/bin:/usr/sbin:/bin:/sbin
unsetenv        CC
unsetenv        CFLAGS
unsetenv        CXX
unsetenv        CXXFLAGS
unsetenv        CPP
unsetenv        CPPFLAGS
unsetenv        FC
unsetenv        FFLAGS
unsetenv        LD
unsetenv        LDFLAGS
unsetenv        LD_LIBRARY_PATH

prepend-path    PATH    $install_prefix/bin:$install_prefix/sbin
prepend-path    MANPATH         $install_prefix/man:/usr/share/man
prepend-path    MODULEPATH      $install_prefix/etc/modulefiles

setenv          PKGSRC          $install_prefix
setenv          PKGSRC_INCLUDE  $install_prefix/include
setenv          PKGSRC_LIB      $install_prefix/lib
EOM

chmod -R a+rX $PREFIX/etc/pkgsrc* $PREFIX/etc/modulefiles

# FIXME: where is pkgdb?
# pkg_admin -K $PREFIX/.pkgdb fetch-pkg-vulnerabilities
pkg_admin fetch-pkg-vulnerabilities

printf "Add $PREFIX/*bin to PATH for all users? y/[n] "
read add
if [ 0$add = 0y ]; then
    if [ -d /etc/profile.d ]; then
	cp $PREFIX/etc/pkgsrc-non-exclusive.* /etc/profile.d
	chmod 644 /etc/profile.d/pkgsrc-non-exclusive.*
    elif [ -d /etc/paths.d ]; then
	cat << EOM > /etc/paths.d/10-pkgsrc
$PREFIX/bin
$PREFIX/sbin
EOM
	chmod 644 /etc/paths.d/10-pkgsrc
    fi
fi
