#
# Copyright (c) 2000,2003 Silicon Graphics, Inc.  All Rights Reserved.
# Copyright (c) 2010 Aconex.  All Rights Reserved.
# 
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
# 
# This file is sourced by PCP scripts to set the environment
# variables defined in the file named $PCP_CONF (or /etc/pcp.conf
# if $PCP_CONF is not defined). Any variable already defined in
# the environment is not changed. 
#
# Note: any variables NOT starting with PCP_ will be ignored.
# This is a security issue so don't change it.
#
if [ -z "$PCP_ENV_DONE" ]
then
    if [ -n "$PCP_CONF" ]
    then
	__CONF="$PCP_CONF"
    elif [ -n "$PCP_DIR" ]
    then
	__CONF="$PCP_DIR/etc/pcp.conf"
    else
	__CONF=/etc/pcp.conf
    fi
    if [ ! -f "$__CONF" ]
    then
	echo "pcp.env: Fatal Error: \"$__CONF\" not found" >&2
	exit 1
    fi
    eval `sed -e 's/"//g' $__CONF \
    | awk -F= '
/^PCP_/ && NF == 2 {
	    exports=exports" "$1
	    printf "%s=${%s:-\"%s\"}\n", $1, $1, $2
	}
END	{ print "export", exports }'`

    # prevent doing all of this more than once per process ...
    #
    export PCP_ENV_DONE=y
fi

# Always need to set $PATH ... sudo -E leaves $PCP_ENV_DONE set, but
# clears/resets $PATH.
#
# Note when we're adding directories into $PATH (as opposed to the
# directory already being in $PATH), the order is important: any
# dirs with PCP-specific binaries should end up ahead of more generic
# dirs in the final $PATH to avoid conflicts with names of non-pcp
# binaries, by ensuring the pcp ones are found first.
#
# Also, there are a small number of commands that we need, e.g. in
# PMDA Install scripts, that are not necessariy on the default $PATH,
# e.g. chown in /usr/sbin on *BSD.  Put these after the PCP ones, but
# ahead of the default $PATH.
#
for dir in /usr/sbin \
	${PCP_BIN_DIR} ${PCP_BINADM_DIR} \
	${PCP_SHARE_DIR}/bin ${PCP_PLATFORM_PATHS}
do
    if [ -d $dir ]
    then
	if echo ":$PATH:" | grep ":$dir:" >/dev/null 2>&1
	then
	    :
	else
	    PATH="$dir:$PATH"
	fi
    fi
done
export PATH

# Also need to always do this because it may be resetting things
# that sudo has cleared from the environment, e.g. PERL5LIB
#
# Optionally augment or over-ride settings with per-user configuration
#
if [ -f $HOME/.pcp/pcp.conf ]
then
    eval `sed -e 's/"//g' -e '/^#/d' $HOME/.pcp/pcp.conf \
    | awk -F= '
NF == 2 {
	exports=exports" "$1
	printf "%s=${%s:-\"%s\"}\n", $1, $1, $2
    }
END	{ print "export", exports }'`
fi

# Find PIDs by matching the name ($1)
# Executable alias name avoidance algorithm ...
# - if name contains a / use it literally and consider nothing else
# - if name matches an executable in $PCP_BIN_DIR, use that full pathname
# - if name matches an executable in $PCP_BINADM_DIR, use that full pathname
# - if find(1) can locate name on this week's $PATH, use that full pathname
# - if name matches an executable in $PCP_BIN_DIR and/or $PCP_BINADM_DIR
#   and/or find(1) matches name, use _all_ of the pathnames in the order
#   above (needed e.g. for pmlogger in $PCP_BIN_DIR and symlink in
#   $PCP_BINADM_DIR)
# - if -a is specified also match on /name (this was the original behaviour
#   before the pathname matching was added)
# - otherwise use name as is
#
_get_pids_by_name()
{
    if [ $# -eq 2 -a "X$1" = X-a ]
    then
	__all=true
	shift
    else
	__all=false
    fi
    if [ $# -ne 1 ]
    then
	echo "Usage: _get_pids_by_name [-a] process-name" >&2
	exit 1
    fi
    if [ "X$tmp" = X ]
    then
	echo "_get_pids_by_name requires a \$tmp setting" >&2
	exit 1
    elif [ -d "$tmp" ]
    then
	__tmp="$tmp/pcp.env"	# from mktemp
    else
	__tmp=$tmp.pcp.env	# from PCP QA
    fi

    __name="$1"
    rm -f $__tmp.*
    touch $__tmp.path
    case "$1"
    in
	*/*)
	    rm -f $__tmp.path
	    ;;
	*)
	    if [ -n "$PCP_BIN_DIR" -a -x "$PCP_BIN_DIR/$1" ]
	    then
		if ! grep "$PCP_BIN_DIR/$1" $__tmp.path >/dev/null
		then
		    echo "$PCP_BIN_DIR/$1" >>$__tmp.path
		fi
	    fi
	    if [ -n "$PCP_BINADM_DIR" -a -x "$PCP_BINADM_DIR/$1" ]
	    then
		if ! grep "$PCP_BINADM_DIR/$1" $__tmp.path >/dev/null
		then
		    echo "$PCP_BINADM_DIR/$1" >>$__tmp.path
		fi
	    fi
	    __which="`which "$1" 2>/dev/null`"
	    if [ -n "$__which" ]
	    then
		if ! grep "$__which" $__tmp.path >/dev/null
		then
		    echo "$__which" >>$__tmp.path
		fi
	    fi
	    ;;
    esac

    # Algorithm ... all ps(1) variants have a time of the form MM:SS
    # or HH:MM:SS or HH:MM.SS before the psargs field, so we're using
    # this as the search anchor.
    #
    # Matches with $1 (process-name) occur if the first psarg is one
    # of the paths identified above or ends in /$1 (if -a specified)
    # or starts ($1) (blame Mac OS X for the last one)
    # ... the matching uses sed's regular expressions, so passing a
    # regex into $1 will work.

    # some preprocessing to condition the ps(1) output lines
    #
    cat <<End-of-File >$__tmp.sed
s/$/ /
s/[ 	][ 	]*/ /g
s/^ //
s/^[^ ]* //
End-of-File
    if [ -f $__tmp.path ]
    then
	# not a literal use of $1, at least one matching pathname found
	#
	sed <$__tmp.path >>$__tmp.sed \
	    -e 's/\//\\\//g' \
	    -e 's/.*/\/[0-9][:\\.][0-9][0-9]  *& \/s\/ .*\/\/p/'
    fi
    # optionally add -a case
    #
    if $__all
    then
	echo "$1" | sed >>$__tmp.sed \
	    -e 's/\//\\\//g' \
	    -e 's/.*/\/[0-9][:\\.][0-9][0-9]  *[^ ]*\\\/& \/s\/ .*\/\/p/'
    fi
    # add literal cases
    #
    # exact match
    echo "$1" | sed >>$__tmp.sed \
	-e 's/\//\\\//g' \
	-e 's/.*/\/[0-9][:\\.][0-9][0-9]  *& \/s\/ .*\/\/p/'
    # Mac OS X variant
    echo "$1" | sed >>$__tmp.sed \
	-e 's/\//\\\//g' \
	-e 's/.*/\/[0-9][:\\.][0-9][0-9]  *(&) \/s\/ .*\/\/p/'

    # need to sort in case of multiple matches from the sed(1) patterns
    #
    $PCP_PS_PROG $PCP_PS_ALL_FLAGS \
    | sed -n -f $__tmp.sed \
    | sort -n -u
    rm -f $__tmp.*
}

# Redundant now ... use _get_pids_by_name -a ...
# Maintained here for backwards compatibility.
#
_get_pids_by_args()
{
    if [ $# -lt 1 ]
    then
	echo "Usage: _get_pids_by_args process-name [args...]" >&2
	exit 1
    fi
    # Matches on command and its arguments ... note escaping any / in
    # the process name happens in _get_pids_by_name()
    #
    _get_pids_by_name -a "$@"
}
