sts=1		# failure is the default
tmp=/var/tmp/pcp-postinstall
trap "rm -rf $tmp $tmp.*; exit \$sts" 0 1 2 3 15

if [ ! -f /etc/pcp.env ]
then
    # PCP not installed ... seems odd
    #
    echo "Error: /etc/pcp.env not installed!"
    exit
fi

. /etc/pcp.env

# set up $PATH to include all the optional and bizarre places that
# useful executables might be hiding
#
for xtra in /usr/sbin /sbin /usr/local/bin "$PCP_BINADM_DIR" \
	    /usr/local/git/bin /usr/perl5/bin /usr/gnu/bin
do
    [ -d "$xtra" ] || continue
    if echo ":${PATH}:" | grep ":$xtra:" >/dev/null 2>&1
    then
	:
    else
	PATH="$PATH:$xtra"
    fi
done
export PATH

here=`pwd`

# -n (show-me) is the only command line option ...
#
if [ $# -eq 1 -a X"$1" = X"-n" ]
then
    show_me=true
    RM="echo + rm"
    MV="echo + mv"
    MKDIR="echo + mkdir"
    CHMOD="echo + chmod"
    CHOWN="echo + chown"
    SYSTEMCTL="echo + systemctl"
    RC_UPDATE="echo + rc-update"
    MAKEWHATIS="echo + makewhatis"
    ADDUSER="echo + adduser"
    USERADD="echo + useradd"
    GROUPADD="echo + groupadd"
    RCCTL="echo + rcctl"
    LDCONFIG="echo + ldconfig"
else
    show_me=false
    RM=rm
    MV=mv
    MKDIR=mkdir
    CHMOD=chmod
    CHOWN=chown
    SYSTEMCTL=systemctl
    RC_UPDATE=rc-update
    MAKEWHATIS=makewhatis
    ADDUSER=adduser
    USERADD=useradd
    GROUPADD=groupadd
    RCCTL=rcctl
    LDCONFIG=ldconfig
fi

_cd()
{
    $show_me && echo "+ cd $1"
    cd $1
}

# no need to touch $PCP_VAR_DIR/pmns/.NeedRebuild as this file
# is included in the tarball
#

for conf in \
    "$PCP_PMCDCONF_PATH" "$PCP_PMCDOPTIONS_PATH" "$PCP_PMCDRCLOCAL_PATH" \
    "$PCP_PMIECONTROL_PATH" "$PCP_PMLOGGERCONTROL_PATH" \
    "$PCP_PMPROXYOPTIONS_PATH" "$PCP_PMWEBDOPTIONS_PATH" \
  # end
do
    if [ -f "$conf.pre" -a -f "$conf" ]
    then
	if diff "$conf" "$conf.pre" >/dev/null 2>&1
	then
	    $RM -f "$conf.pre"
	else
	    # if $conf.pre is zero sized (maybe a previous filesystem
	    # full or reconfig that failed), so that's probably not
	    # a good thing to leave in place ...
	    #
	    if [ -s "$conf.pre" ]
	    then
		$MV "$conf" "$conf.dist"
		$MV "$conf.pre" "$conf"
		echo "Warning: $conf: original restored, new version in $conf.dist"
		ls -l $conf $conf.dist
	    else
		echo "Warning: $conf: previous version is empty, not restored"
		ls -l $conf.pre $conf
		$RM -f "$conf.pre"
	    fi
	fi
    fi
done

# set up pcp and pcpqa users
#
if [ -f /etc/passwd ]
then
    # things like useradd may be hiding in odd places ...
    #
    PATH="$PATH":/usr/sbin
    # common command-line options
    # -c comment
    # -g primary_group_name
    # -d home_directory
    # -m create home directory
    # -s shell
    # command-line variations
    # do not create home directory
    # 	-M for Linux, nothing for netbsd or openbsd
    # system account (no aging, sys gid/uid range, no home dir creation)
    #   -r for Linux, not supported for netbsd or openbsd
    #
    if [ "$PCP_PLATFORM" = netbsd ]
    then
	no_home_dir=''
	sys_acc=''
	nologin=/sbin/nologin
	bash=/usr/pkg/bin/bash
    elif [ "$PCP_PLATFORM" = openbsd ]
    then
	no_home_dir=''
	sys_acc=''
	nologin=/sbin/nologin
	bash=`which bash`
    elif [ "$PCP_PLATFORM" = solaris ]
    then
	no_home_dir=''
	sys_acc=''
	nologin=`which false`
	bash=`which bash`
    elif [ "$PCP_PLATFORM" = darwin ]
    then
	no_home_dir=''
	sys_acc=''
	nologin=`which false`
	bash=`which bash`
    else
	no_home_dir='-M'
	sys_acc='-r'
	nologin=/usr/sbin/nologin
	bash=/bin/bash
    fi

    # user & group pcp
    #
    if [ "$PCP_PLATFORM" = darwin ]
    then
	./useradd.darwin -c "Performance Co-Pilot" -g pcp -d "$PCP_VAR_DIR" -s $nologin pcp
    else
	if grep '^pcp:' /etc/group >/dev/null
	then
	    :
	else
	    if which groupadd >/dev/null 2>&1
	    then
		$GROUPADD $sys_acc pcp
	    else
		if [ "$PCP_PLATFORM" = freebsd ]
		then
		    : adduser does this for us ...
		else
		    echo "postinstall: Error: don't know how to add group \"pcp\""
		    exit
		fi
	    fi
	fi
	if grep '^pcp:' /etc/passwd >/dev/null
	then
	    :
	else
	    if which useradd >/dev/null 2>&1
	    then
		$USERADD -c "Performance Co-Pilot" -g pcp -d "$PCP_VAR_DIR" $no_home_dir $sys_acc -s $nologin pcp
	    elif which adduser >/dev/null 2>&1
	    then
		echo "pcp::::::Performance Co-Pilot:$PCP_VAR_DIR::" \
		| $ADDUSER -f - -w no
		else
		echo "postinstall: Error: don't know how to add user \"pcp\""
		exit
		fi
	fi
    fi

    # user & group pcpqa
    #
    if [ "$PCP_PLATFORM" = darwin ]
    then
	./useradd.darwin -c "PCP Quality Assurance" -g pcpqa -d "$PCP_VAR_DIR"/testsuite -s $bash pcpqa
    else
	if grep '^pcpqa:' /etc/group >/dev/null
	then
	    :
	else
	    if which groupadd >/dev/null 2>&1
	    then
		$GROUPADD $sys_acc pcpqa
	    else
		if [ "$PCP_PLATFORM" = freebsd ]
		then
		    : adduser does this for us ...
		else
		    echo "postinstall: Error: don't know how to add group \"pcpqa\""
		    exit
		fi
	    fi
	fi
	if grep '^pcpqa:' /etc/passwd >/dev/null
	then
	    :
	else
	    if which useradd >/dev/null 2>&1
	    then
		$USERADD -c "PCP Quality Assurance" -g pcpqa -d "$PCP_VAR_DIR"/testsuite $no_home_dir $sys_acc -s $bash pcpqa
	    elif which adduser >/dev/null 2>&1
	    then
		# no bash for default FreeBSD
		bash=`which sh`
		echo "pcpqa::::::PCP Quality Assurance:$PCP_VAR_DIR/testsuite:$bash:" \
		| $ADDUSER -f - -w no
	    else
		echo "postinstall: Error: don't know how to add user \"pcpqa\""
		exit
	    fi
	fi
    fi
fi

# Usage: _do_dir user:group mode path
_do_dir()
{
    dir="$3"
    if $show_me
    then
	$MKDIR -p "$dir"
    else
	[ -d "$dir" ] || $MKDIR -p "$dir"
    fi
    $CHOWN "$1" "$dir"
    $CHMOD "$2" "$dir"
}

# permissions ...
#

# fix up some ones that used to be pcp:pcp and/or in a different place
#
grp=root
case "$PCP_PLATFORM"
in
    freebsd|netbsd|openbsd|darwin)
	    grp=wheel
	    ;;
esac
for daemon in pmlogger pmie
do
    $CHOWN root:"$grp" "$PCP_SYSCONF_DIR"/"$daemon"
    $CHMOD 755 "$PCP_SYSCONF_DIR"/"$daemon"
    if [ -f "$PCP_SYSCONF_DIR"/"$daemon"/config.default ]
    then
	if [ -f "$PCP_VAR_DIR"/config/"$daemon"/config.default ]
	then
	    $MV "$PCP_SYSCONF_DIR"/"$daemon"/config.default "$PCP_VAR_DIR"/config/"$daemon"/config.default.old
	else
	    $MV "$PCP_SYSCONF_DIR"/"$daemon"/config.default "$PCP_VAR_DIR"/config/"$daemon"/config.default
	fi
    fi
done
$CHOWN "root:$grp" "$PCP_SYSCONF_DIR"/pmcd/pmcd.conf
$CHMOD 644 "$PCP_SYSCONF_DIR"/pmcd/pmcd.conf

# /etc/pcp.conf and /etc/pcp.env should be owned by root (for consistency,
# no functional reason)
#
$CHOWN "root:$grp" /etc/pcp.conf /etc/pcp.env

# if $PCP_SYSCONFIG_DIR is defined, all the PCP files below there should
# to be owned by root
#
if [ -n "$PCP_SYSCONFIG_DIR" ]
then
    for daemon in pmcd pmlogger pmproxy
    do
	[ -f "$PCP_SYSCONFIG_DIR/$daemon" ] || continue
	$CHOWN "root:$grp" "$PCP_SYSCONFIG_DIR/$daemon"
    done
fi

# if $PCP_SYSTEMDUNIT_DIR is defined, all the PCP files below there should
# to be owned by root
#
if [ -n "$PCP_SYSTEMDUNIT_DIR" ]
then
    for service in pmcd pmlogger pmie pmproxy
    do
	[ -f "$PCP_SYSTEMDUNIT_DIR/$service.service" ] || continue
	$CHOWN "root:$grp" "$PCP_SYSTEMDUNIT_DIR/$service.service"
    done
fi

# if $PCP_SASLCONF_DIR is defined, the PCP config file there should be
# owned by root
#
if [ -n "$PCP_SASLCONF_DIR" ]
then
    [ -f "$PCP_SASLCONF_DIR/pmcd.conf" ] && $CHOWN "root:$grp" "$PCP_SASLCONF_DIR/pmcd.conf"
fi

# all the /etc/cron.d PCP files MUST be owned my root
#
for file in /etc/cron.d/pcp-*
do
    [ -f "$file" ] && $CHOWN "root:$grp" "$file"
done

# directories that may be empty and hence not in the tarball
#
# from GNUmakefile
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/labels
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/labels/optional
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pmcheck
if [ -d "$PCP_PMDAS_DIR"/openmetrics ]
then
    # from src/pmdas/openmetrics
    _do_dir "root:$grp" 755 "$PCP_PMDAS_DIR"/openmetrics/config.d
fi
# from src/pmcd/GNUmakefile
_do_dir "root:$grp" 700 "$PCP_VAR_DIR"/pmcd
_do_dir "root:$grp" 755 "$PCP_LOG_DIR"/pmcd
# from src/pmfind/GNUmakefile
_do_dir "pcp:pcp" 775 "$PCP_LOG_DIR"/pmfind
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pmfind
# from src/pmdas/pipe/GNUmakefile
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pipe.conf.d
# from src/pmdas/bash/GNUmakefile
_do_dir "pcp:pcp" 775 "$PCP_TMP_DIR"/bash
# from src/pmdas/json/GNUmakefile
_do_dir "pcp:pcp" 775 "$PCP_TMP_DIR"/json
# from src/pmchart/views/GNUmakefile
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pmchart
_do_dir "root:$grp" 755 "$PCP_VAR_DIR"/config/pmchart
# from src/pmieconf/GNUmakefile.rules
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pmieconf/entropy
_do_dir "root:$grp" 755 "$PCP_VAR_DIR"/config/pmieconf/entropy
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/pmieconf/power
_do_dir "root:$grp" 755 "$PCP_VAR_DIR"/config/pmieconf/power
# from src/pcp/htop/GNUmakefile
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/htop
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/htop/meters
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/htop/columns
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/htop/screens
# from src/pmcd/GNUmakefile
_do_dir "root:$grp" 700 "$PCP_VAR_DIR"/pmcd
# from src/pmdas/opentelemetry/GNUmakefile
_do_dir "root:$grp" 755 "$PCP_SYSCONF_DIR"/opentelemetry
_do_dir "root:$grp" 755 "$PCP_PMDAS_DIR"/opentelemetry/config.d

# Expect only root owned things below $PCP_SYSCONF_DIR
#
find "$PCP_SYSCONF_DIR" ! -user root \
| while read f
do
    if [ -L "$f" ]
    then
	# change the symlink, not what it points to
	#
	$CHOWN -h "root:$grp" "$f"
    else
	$CHOWN "root:$grp" "$f"
    fi
done

# pcp:pcp and mode 775 directories
#
for dir in "$PCP_LOG_DIR" \
	   "$PCP_LOG_DIR"/pmproxy \
	   "$PCP_LOG_DIR"/pmie "$PCP_LOG_DIR"/pmlogger \
	   "$PCP_SA_DIR" \
	   "$PCP_RUN_DIR" \
	   "$PCP_TMP_DIR" "$PCP_TMP_DIR"/pmie "$PCP_TMP_DIR"/pmlogger \
	   "$PCP_TMP_DIR"/mmv "$PCP_TMP_DIR"/pmproxy \
	   "$PCP_VAR_DIR"/config/pmda \
	   "$PCP_VAR_DIR"/config/pmie "$PCP_VAR_DIR"/config/pmlogger \
    # end
do
    _do_dir "pcp:pcp" 775 "$dir"
done

# pcp:pcp and mode 644 files
#
for file in "$PCP_VAR_DIR"/config/pmie/config.default "$PCP_VAR_DIR"/config/pmlogger/config.default
do
    [ -f "$file" ] || continue
    $CHMOD 644 "$file"
    $CHOWN pcp:pcp "$file"
done

# pcpqa:pcpqa and mode 775 dir and all below there
#
_do_dir "pcpqa:pcpqa" 775 "$PCP_VAR_DIR"/testsuite
$CHOWN -R pcpqa:pcpqa "$PCP_VAR_DIR"/testsuite

rm -f $tmp.errors
# unpack and install PCP Perl modules ...
#
if [ -f /tmp/pcp-perl-pack.tar.gz ]
then
    eval `sed -n '/^TAR[ 	]*=/s/[ 	]//gp' </usr/include/pcp/builddefs`
    if [ -z "$TAR" ]
    then
	echo "postinstall: no TAR in /usr/include/pcp/builddefs ... skipping Perl bits"
    else
	rm -rf /tmp/pcp-postinstall
	mkdir /tmp/pcp-postinstall
	_cd /tmp/pcp-postinstall
	$TAR xzf ../pcp-perl-pack.tar.gz
	for dir in *
	do
	    if [ ! -f $dir/Makefile ]
	    then
		echo "postinstall: no $dir/Makefile ... cannot install $dir Perl module"
		touch $tmp.errors
	    else
		_cd $dir
		if $show_me
		then
		    echo "+ make -f Makefile pure_site_install"
		else
		    if make -f Makefile pure_site_install
		    then
			:
		    else
			echo "postinstall: install failed for $dir ..."
			touch $tmp.errors
		    fi
		fi
		_cd ..
	    fi
	done
	_cd $here
    fi
fi

# Note:
#   Do not start daemons other than: pmcd, pmlogger, pmie,
#   pmproxy
#
if which svcs >/dev/null 2>&1
then
    # in Solaris land, we need an XML file to control all of this
    #
    if [ ! -f ../sun/pcp.xml ]
    then
	echo "Warning: Solaris SMF XML missing: ../sun/pcp.xml"
    else
	svccfg import ../sun/pcp.xml
    fi
else
    for svc in pmcd pmie pmlogger pmproxy pmfind
    do
	if which systemctl >/dev/null 2>&1
	then
	    $SYSTEMCTL daemon-reload
	    case "$svc"
	    in
		pmcd|pmlogger|pmie|pmproxy)
		    $SYSTEMCTL enable $svc.service
		    $SYSTEMCTL start $svc.service
		    ;;
	    esac
	elif which rc-update >/dev/null 2>&1
	then
	    if [ -f /etc/init.d/"$svc" ]
	    then
		if $RC_UPDATE show | grep " $svc " >/dev/null 2>&1
		then
		    # service is already installed ...
		    #
		    $RC_UPDATE delete "$svc"
		fi
		$RC_UPDATE add "$svc"
	    fi
	elif which rcctl >/dev/null 2>&1
	then
	    # OpenBSD
	    case "$svc"
	    in
		pmcd|pmlogger|pmie|pmproxy)
		    $RCCTL enable $svc
		    $RCCTL start $svc
		    ;;
	    esac
	fi
    done
fi

# optionally update the apropos/whatis/man-k database of man pages
# ... this can take a long time, so it is run in the background
#
if which makewhatis >/dev/null 2>&1
then
    echo "Rebuilding whatis DB in the background"
    $MAKEWHATIS &
fi

# optionally update the shared library cache
#
if which ldconfig >/dev/null 2>&1
then
    echo "Rebuilding shared library cache"
    libs="$PCP_LIB_DIR"
    [ "$PCP_LIB32_DIR" != "$PCP_LIB_DIR" ] && libs="$libs $PCP_LIB32_DIR"
    # check for -m (merge) option for ldconfig(1)
    # FreeBSD 14.3 has usage: ldconfig [-32] [-BRimr] ...
    # OpenBSD 7.9 has usage: ldconfig [-mRrsUv]
    #
    if ldconfig '-?' 2>&1 | grep -E -q '(\[-[^]]*m)|( -m )'
    then
	# we have a -m, use that to merge (rather than clobber)
	#
	$LDCONFIG -m $libs
    else
	# else no -m, so rebuild everything
	#
	$LDCONFIG $libs
    fi
fi

# cull any old files or directories that used to be in the distribution
# but that have gone away or moved somewhere else
#
for file in "$PCP_VAR_DIR"/config/pmieconf/pcp/pmda_status \
	    "$PCP_VAR_DIR"/config/pmlogger/crontab.docker \
	    "$PCP_VAR_DIR"/config/pmie/crontab.docker \
	    "$PCP_VAR_DIR"/config/pmlogconf/storage/farm \
	    "$PCP_VAR_DIR"/pmns/xfs \
	    "$PCP_BINADM_DIR"/pmmgr "$PCP_RC_DIR"/pmmgr /etc/init.d/pmmgr \
	    "$PCP_SYSCONF_DIR"/pmrep/pmrep.conf \
	    "$PCP_PMDAS_DIR"/activemq/*.pm \
	    "$PCP_PMDAS_DIR"/postgresql/pmdapostgresql.pl \
	    "$PCP_PMDAS_DIR"/nfsclient/pmdanfsclient.pl \
	    "$PCP_PMDAS_DIR"/elasticsearch/pmdaelasticsearch.pl \
	    "$PCP_PMDAS_DIR"/kvm/pmdakvm.pl \
	    "$PCP_PMDAS_DIR"/lmsensors/pmdalmsensors \
	    "$PCP_SHARE_DIR"/lib/pmlogger "$PCP_SHARE_DIR"/lib/pmproxy \
	    "$PCP_SHARE_DIR"/lib/pmmgr "$PCP_SHARE_DIR"/lib/pmie \
	    "$PCP_SHARE_DIR"/lib/pmcd "$PCP_SHARE_DIR"/lib/pmwebd \
	    "$PCP_SHARE_DIR"/lib/pcp \
	    "$PCP_SHARE_DIR"/bin/logdecompress \
	    "$PCP_ETC_DIR"/pcp/pmlogconf/kernel/*-irix \
	    "$PCP_VAR_DIR"/config/pmlogconf/kernel/*-irix \
	    "$PCP_ETC_DIR"/pcp/pmlogconf/networking/*-irix \
	    "$PCP_VAR_DIR"/config/pmlogconf/networking/*-irix \
	    "$PCP_ETC_DIR"/pcp/pmlogconf/memory/*-irix \
	    "$PCP_VAR_DIR"/config/pmlogconf/memory/*-irix \
	    "$PCP_ETC_DIR"/pcp/pmlogger/crontab.docker \
	    "$PCP_ETC_DIR"/pcp/pmie/crontab.docker \
	    "$PCP_ETC_DIR"/pcp/pmproxy/pmproxy.defaults \
	    "$PCP_ETC_DIR"/pcp/pmrep/xtract-names \
	    "$PCP_ETC_DIR"/pcp/pmlogger/rc \
	    "$PCP_ETC_DIR"/pcp/pmproxy/rc \
	    "$PCP_ETC_DIR"/pcp/pmie/rc \
	    "$PCP_ETC_DIR"/pcp/pmlogconf/storage/farm \
    # end
do
    [ -f "$file" -o -L "$file" ] && $RM -f "$file"
done
if [ -n "$PCP_SYSTEMDUNIT_DIR" ]
then
    for file in pmmgr.service pmfind.path pmie_check.path pmlogger_check.path \
	pmmgr.service pmwebd.service \
	pmlogger_daily-poll.service pmlogger_daily-poll.timer \
	pmlogger_daily_poll.service pmlogger_daily_poll.timer \
	pmlogger_daily_report-poll.service pmlogger_daily_report-poll.timer \
	pmlogger_daily_report_poll.service pmlogger_daily_report_poll.timer \
	pmlogger_daily_report.service pmlogger_daily_report.timer
    do
	[ -f "$PCP_SYSTEMDUNIT_DIR/$file" ] && $RM -f "$PCP_SYSTEMDUNIT_DIR/$file"
    done
fi
for dir in "$PCP_VAR_DIR"/config/pmieconf/pcp \
	   "$PCP_LOG_DIR"/pmmgr "$PCP_ETC_DIR"/pcp/pmmgr \
	   "$PCP_ETC_DIR"/pcp/pmcheck \
	   "$PCP_DEMOS_DIR"/json \
	   "$PCP_SHARE_DIR"/webapps \
	   "$PCP_PMDAS_DIR"/prometheus \
	   "$PCP_ETC_DIR"/pcp/htop \
	   "$PCP_ETC_DIR"/pcp/json \
	   "$PCP_ETC_DIR"/pcp/pmlogconf/v1.0 \
	   "$PCP_VAR_DIR"/config/pmlogconf/v1.0 \
	   "$PCP_ETC_DIR"/pcp/pmlogconf/sgi \
	   "$PCP_VAR_DIR"/config/pmlogconf/sgi \
	   "$PCP_ETC_DIR"/pcp/pmwebd \
	   "$PCP_ETC_DIR"/pcp/ohead \
    # end
do
    [ -d "$dir" ] && $RM -rf "$dir"
done

[ ! -f $tmp.errors ] && sts=0
exit 0
