MLE:a_tty_readline(): FIX possible buffer-overflow with HAVE_KEY_BINDINGS..
[s-mailx.git] / mk / su-find-command.sh
blob2f0c62628fe74cc2dbe37f9e46bd20ef337f56c5
1 #!/bin/sh -
2 #@ Find an executable command within a POSIX shell.
3 #@ which(1) is not standardized, and command(1) -v may return non-executable,
4 #@ so here is how it is possible to really find a usable executable file.
5 #@ Use like this:
6 #@ thecmd_testandset chown chown ||
7 #@ PATH="/sbin:${PATH}" thecmd_set chown chown ||
8 #@ PATH="/usr/sbin:${PATH}" thecmd_set_fail chown chown
9 #@ or
10 #@ thecmd_testandset_fail MAKE make
11 #@ or
12 #@ MAKE=/usr/bin/make thecmd_testandset_fail MAKE make
14 # 2017 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
15 # Thanks to Robert Elz (kre).
16 # Public Domain
18 ## First of all, the actual functions need some environment:
20 if [ -z "${SU_FIND_COMMAND_INCLUSION}" ]; then
21 VERBOSE=1
23 ( set -o noglob ) >/dev/null 2>&1 && noglob_shell=1 || unset noglob_shell
25 msg() {
26 fmt=${1}
27 shift
28 printf >&2 -- "${fmt}\n" "${@}"
32 ## The actual functions
34 acmd_test() { fc__acmd "${1}" 1 0 0; }
35 acmd_test_fail() { fc__acmd "${1}" 1 1 0; }
36 acmd_set() { fc__acmd "${2}" 0 0 0 "${1}"; }
37 acmd_set_fail() { fc__acmd "${2}" 0 1 0 "${1}"; }
38 acmd_testandset() { fc__acmd "${2}" 1 0 0 "${1}"; }
39 acmd_testandset_fail() { fc__acmd "${2}" 1 1 0 "${1}"; }
40 thecmd_set() { fc__acmd "${2}" 0 0 1 "${1}"; }
41 thecmd_set_fail() { fc__acmd "${2}" 0 1 1 "${1}"; }
42 thecmd_testandset() { fc__acmd "${2}" 1 0 1 "${1}"; }
43 thecmd_testandset_fail() { fc__acmd "${2}" 1 1 1 "${1}"; }
45 ## -- >8 - - 8< -- ##
47 fc__pathsrch() { # pname=$1 exec=$2 varname=$3 verbok=$4
48 fcps__pname=$1 fcps__exec=$2 fcps__varname=$3 fcps__verbok=$4
50 # It may be an absolute path, check that first
51 if [ "${fcps__exec}" != "${fcps__exec#/}" ] &&
52 [ -f "${fcps__exec}" ] && [ -x "${fcps__exec}" ]; then
53 [ -n "${VERBOSE}" ] && [ ${fcps__verbok} -ne 0 ] &&
54 msg ' . ${%s} ... %s' \
55 "${fcps__pname}" "${fcps__exec}"
56 [ -n "${fcps__varname}" ] &&
57 eval "${fcps__varname}"="${fcps__exec}"
58 return 0
61 # Manual search over $PATH
62 fcps__oifs=${IFS} IFS=:
63 [ -n "${noglob_shell}" ] && set -o noglob
64 set -- ${PATH}
65 [ -n "${noglob_shell}" ] && set +o noglob
66 IFS=${fcps__oifs}
67 for fcps__path
69 if [ -z "${fcps__path}" ] || [ "${fcps__path}" = . ]; then
70 if [ -d "${PWD}" ]; then
71 fcps__path=${PWD}
72 else
73 fcps__path=.
76 if [ -f "${fcps__path}/${fcps__exec}" ] &&
77 [ -x "${fcps__path}/${fcps__exec}" ]; then
78 [ -n "${VERBOSE}" ] && [ ${fcps__verbok} -ne 0 ] &&
79 msg ' . ${%s} ... %s' \
80 "${fcps__pname}" "${fcps__path}/${fcps__exec}"
81 [ -n "${fcps__varname}" ] &&
82 eval "${fcps__varname}"="${fcps__path}/${fcps__exec}"
83 return 0
85 done
86 return 1
89 fc__acmd() {
90 fca__pname=${1} fca__dotest=${2} fca__dofail=${3} \
91 fca__verbok=${4} fca__varname=${5}
93 if [ "${fca__dotest}" -ne 0 ]; then
94 eval fca__dotest=\$${fca__varname}
95 if [ -n "${fca__dotest}" ]; then
96 if fc__pathsrch "${fca__pname}" "${fca__dotest}" "${fca__varname}" \
97 ${fca__verbok}; then
98 return 0
100 msg 'WARN: ignoring non-executable ${%s}=%s' \
101 "${fca__pname}" "${fca__dotest}"
105 if fc__pathsrch "${fca__pname}" "${fca__pname}" "${fca__varname}" \
106 ${fca__verbok}; then
107 return 0
110 [ -n "${fca__varname}" ] && eval "${fca__varname}"=
111 [ ${fca__dofail} -eq 0 ] && return 1
112 msg 'ERROR: no trace of utility '"${fca__pname}"
113 exit 1
116 # s-sh-mode