#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------
set -u

# A safe way to run something with a controlled shell environment defined by
# sourcing /p4/common/bin/p4_vars with a given SDP instance.

# Usage:
#   p4master_run INSTANCE [-c] PROGRAM [PROGRAM_ARGS ...]
#
# where INSTANCE is an SDP instance number or name.
function usage {
   echo -e "\nUsage:
\tp4master_run INSTANCE [-c] PROGRAM [ARGS ...]

where INSTANCE is an SDP instance number or name.

The optional '-c' flag is for running programs from cron that
send their own emails.  It suppresses some errors to avoid
duplicate emails from the cron daemon.  Some errors, such as
failures to start the called program, still are reported by
cron email.

PROGRAM can be a relative or absolute path, with optional arguments.\n"
exit 3
}

# Bail with usage message if there are less than 2 arguments.
[[ $# -lt 2 ]] && usage

Instance=${1:-Unset}

# Do nothing unless $Instance is defined.  Make sure user didn't
# try to pass a flag (e.g. '-c') as the first parameter.
if [[ $Instance == Unset || $Instance == -* ]]; then
   echo -e "\nError: The Perforce instance name must be the first parameter. Aborting.\n" >&2
   usage
fi

# Save original full set of arguments.  The shift will lose the instance
# argument, which will cause this to fail if you run it as root, and it
# tries to rerun as $OSUSER.
AllArgs="$@"

shift

# Bail with usage message if nothing follows '-c'.
if [[ $1 == -c ]]; then
   [[ $# -lt 2 ]] && usage
   CRON=yes
   shift
fi

SDP_CONF=/p4/common/bin/p4_vars

if [[ ! -r "$SDP_CONF" ]]; then
 echo -e "\nError: No readable SDP config file [$SDP_CONF]. Aborting.\n" >&2
 exit 2
fi

# Load SDP controlled shell environment.
source "$SDP_CONF" "$Instance" ||\
   { echo -e "\nError: Failed to load SDP environment.\n"; exit 1; }

if [[ $(id -u) -eq 0 ]]; then
   exec su - $OSUSER -c "$0 $AllArgs"
elif [[ $(id -u -n) != $OSUSER ]]; then
   echo "$0 can only be run by root or $OSUSER"
   exit 1
fi

Program=$1
if [[ $Program == /* || $Program == \.* ]]; then
   # Non-path dependent, absolute or relative path specified.
   ProgramPath=$Program
else
   # Path-dependent path specified.
   ProgramPath=$(which $Program)
fi

if [[ -z "$ProgramPath" ]]; then
   echo -e "\nError: The specified program [$Program] cannot be found.  Aborting.\n" >&2
   exit 3
fi

if [[ ! -r "$ProgramPath" ]]; then
   echo -e "\nError: The specified program [$Program] cannot be found.  Aborting.\n" >&2
   exit 3
fi

if [[ ! -x "$ProgramPath" ]]; then
   echo -e "\nError: The specified program [$Program] is not executable.  Aborting.\n" >&2
   exit 3
fi

shift
Args=$@

$Program $Args