#! /bin/sh

# Copyright (c) 2003-2013
# Distributed Systems Software.  All rights reserved.
# See the file LICENSE for redistribution information.
#
# $Id: printpath-sh 2617 2013-01-22 17:06:50Z brachman $

# Look for a filename within a search path; if found, print its pathname.
#
# By default, search for an executable file using environment variable PATH,
# a search path consisting of a colon-separated list of directories,
# where "executable" means the file is not a directory and "test -x" evaluates
# to True.
#
# The -P flag specifies a search path to use instead of $PATH.
# The -t flag specifies a testing condition to replace the default;
# for example:
#   printpath-sh -t "-w" myfile
# will look for a writable (by the user) instance of myfile in $PATH, printing
# its full pathname if found.
# The -n flag specifies no searching; test if the pathname argument satisfies
# the test condition, ignoring any search path.
# The -q flag specifies quiet operation; output nothing.
# The -- flag specifies the end of flag arguments.
# Flags may appear in any order, but the filename must appear last.
#
# The exit status is 0 if the file was found, 1 otherwise or on error.
#
# This is not intended to work exactly like Apache's PrintPath.

search_path=
quiet_flag=
test_flag=

usage()
{

  echo "Usage: printpath [-P paths] [-t test-flag] [-n] [-q] [--] filename"
  exit 1
  # No return
}

# Usage: pathname_test pathname
# Return 0 if pathname satisfies TEST_FLAG (or the default), 1 otherwise
pathname_test()
{

  pathname="$1"

  if test -z "$test_flag"
  then
    if test -x "$pathname" -a ! -d "$pathname"
    then
      return 0
    fi
  else
    if test "$test_flag" "$pathname"
    then
      return 0
    fi
  fi

  return 1
}

# Usage: do_search filename
# Look for a file named FILENAME in SEARCH_PATH (a colon-separated list of
# directories) that satisfies TEST_FLAG to test(1) if given (otherwise, check
# if FILENAME is an executable, non-directory file).
# If found, emit the pathname to stdout and return 0, otherwise return 1.
do_search()
{

  file="$1"
  oifs="$IFS"
  IFS=":"
  set $search_path
  IFS="$oifs"

  for i
  do
    pathname_test "$i/$file"
    if test $? = 0
    then
      if test -z "$quiet_flag"
      then
        echo "$i/$file"
      fi
      return 0
    fi
  done

  # Not found
  return 1
}

# Examine command line arguments

no_search_flag=
path_list=
while test -n "$1"
do
  case "$1" in
  -P)
    shift
    if test -n "$path_list"
    then
      usage
    fi
    path_list="$1"
    shift
    ;;
  -n)
    no_search_flag=1
    shift
    ;;
  -q)
    quiet_flag=1
    shift
    ;;
  -t)
    shift
    if test -n "$test_flag"
    then
      usage
    fi
    test_flag="$1"
    shift
    ;;
  --)
    shift
    break
    ;;
  *)
    break
    ;;
  esac
done

if test -z "$1" -o $# != 1
then
  usage
fi

filename="$1"

if test -n "$no_search_flag"
then
  pathname_test "$filename"
  rc="$?"
  if test "$rc" = 0 -a -z "$quiet_flag"
  then
    echo $filename
  fi

  exit $rc
fi

if test -n "$path_list"
then
  search_path="$path_list"
else
  search_path="$PATH"
fi

do_search "$filename"

exit $?
