pkgsrc/mk/scripts/shell-lib
maya 6c25dec844 Remove clauses 3,4 from TNF-only copyright blocks.
This is based on the decision The NetBSD Foundation made in 2008 to
do so, which was already applied to src.

This change has been applied to code which is likely not in other
repositories.

ok board@, reviewed by riastradh@
2018-08-22 20:48:36 +00:00

378 lines
11 KiB
Text

# $NetBSD: shell-lib,v 1.5 2018/08/22 20:48:37 maya Exp $
#
# Copyright (c) 2004 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Johnny C. Lam.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
######################################################################
# msg_log logfile msg
# Output msg to logfile. If logfile is "stdout" or "stderr"
# then output to there instead.
######################################################################
msg_log()
{
: ${echo=echo}
_msg_log="$1"; shift
case $_msg_log in
stdout) $echo "$@" ;;
stderr) $echo "$@" 1>&2 ;;
*) $echo "$@" >> $_msg_log ;;
esac
}
######################################################################
# die msg
# Output $msg to stderr, and exit with a positive error code.
######################################################################
die()
{
msg_log stderr "$@"
exit 1
}
######################################################################
# check_prog var prog ...
# If $var is empty or unset, then set it to the path of one of
# the program names in the list.
######################################################################
check_prog()
{
: ${test=test}
_ckp_var="$1"; shift
eval _ckp_tmp=\"\$$_ckp_var\"
if $test "x$_ckp_tmp" != "x"; then
return 0
fi
for _ckp_prog do
_ckp_IFS="${IFS}"; IFS=":"
for _ckp_dir in ${PATH}; do
if $test -x "$_ckp_dir/$_ckp_prog"; then
eval $_ckp_var=\""$_ckp_dir/$_ckp_prog"\"
return 1
fi
done
IFS="${_ckp_IFS}"
done
die "$_ckp_var could not be set."
}
######################################################################
# shquote arg
# Returns a backslashed and quoted version of arg in $shquoted.
######################################################################
shquote()
{
: ${echo=echo}
: ${sed=sed}
_shq_arg=$1
_shq_sed="$sed -e 1s/^X//"
_shq_sed_quote_subst='s/\([\`\"$\\]\)/\\\1/g'
case $_shq_arg in
*[\`\"\$\\]*)
shquoted=`$echo "X$_shq_arg" | $_shq_sed -e "$_shq_sed_quote_subst"`
;;
*)
shquoted="$_shq_arg"
;;
esac
case $shquoted in
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
shquoted="\"$shquoted\""
;;
esac
}
######################################################################
# lock_file -f path [-n token]
# Attempt to create a lockfile at $path. Any directories in the
# path should already exist. If $token is specified, then assume
# that it is unique between machines sharing an NFS mount.
#
# (1) Create globally-unique filename in the same filesystem as the
# lockfile.
# (2) Try to create a hard-link from this file to the lockfile, but
# ignoring any errors.
# (3) If the two files are the same file, then the lock was successfully
# obtained; otherwise, the lock attempt wasn't successful.
######################################################################
lock_file()
{
: ${dirname=dirname}
: ${echo=echo}
: ${link=link}
: ${mkdir=mkdir}
: ${mktemp=mktemp}
: ${rm=rm}
: ${test=test}
: ${touch=touch}
_lf_lockfile=
_lf_nfs=
while $test $# -gt 0; do
case $1 in
-f) _lf_lockfile="$2"; shift ;;
-n) _lf_nfs="$2"; shift ;;
esac
shift
done
if $test -z "$_lf_lockfile"; then
$echo 1>&2 "$0: no lock file specified."
exit
fi
_lf_pid=$$
_lf_lockdir=`$dirname $_lf_lockfile`
_lf_uniqfile=`$mktemp "$_lf_lockdir/.lock.$_lf_nfs.$_lf_pid.XXXXXX" 2>/dev/null` || return 1
if $test -n "$_lf_nfs"; then
{ $echo $_lf_pid; $echo $_lf_nfs; } > $_lf_uniqfile
else
$echo $_lf_pid > $_lf_uniqfile
fi
$link $_lf_uniqfile $_lf_lockfile 2>/dev/null
if $test $_lf_uniqfile -ef $_lf_lockfile; then
_lf_result=0
else
_lf_result=1
fi
$rm -f $_lf_uniqfile
return $_lf_result
}
######################################################################
######################################################################
###
### Queue routines. The queue is implemented as a set of variables
### that is unique to each queue name, thus the use of multiple queues
### is allowed.
###
######################################################################
######################################################################
######################################################################
# init_queue name
# Initialize the named queue.
######################################################################
init_queue()
{
_qname="$1"
eval "_q${_qname}head=1111111111"
eval "_q${_qname}tail=1111111111"
}
######################################################################
# append_queue name item ...
# Append items onto the end of the named queue in FIFO order.
######################################################################
append_queue()
{
: ${test=test}
_qname="$1"; shift
while $test $# -gt 0; do
eval "_qtail=\"\$_q${_qname}tail\""
eval "_q${_qname}${_qtail}=\"\${1}\""
case $_qtail in
*000000000) _qtail=${_qtail%000000000}1 ;;
*) _qtail=${_qtail}0 ;;
esac
eval "_q${_qname}tail=\"\${_qtail}\""
shift
done
}
######################################################################
# prepend_queue name item ...
# Prepend items to the head of the named queue in LIFO order.
######################################################################
prepend_queue()
{
: ${test=test}
_qname="$1"; shift
while $test $# -gt 0; do
eval "_qhead=\"\$_q${_qname}head\""
case $_qhead in
*1) _qhead=${_qhead%1}000000000 ;;
*) _qhead=${_qhead%0} ;;
esac
eval "_q${_qname}${_qhead}=\"\${1}\""
eval "_q${_qname}head=\"\${_qhead}\""
shift
done
}
######################################################################
# head_queue name var
# Return the head of the named queue in $var.
######################################################################
head_queue()
{
_qname="$1"; shift
eval "_qhead=\"\$_q${_qname}head\""
eval "${1}=\"\$_q${_qname}${_qhead}\""
}
######################################################################
# pop_queue name var
# Pop off the head of the named queue and return it in $var.
######################################################################
pop_queue()
{
_qname="$1"; shift
head_queue $_qname $1
case $_qhead in
*000000000) _qhead=${_qhead%000000000}1 ;;
*) _qhead=${_qhead}0 ;;
esac
eval "_q${_qname}head=\"\${_qhead}\""
}
######################################################################
# queue_is_empty name
# Return 0 if the named queue is empty and 1 otherwise.
######################################################################
queue_is_empty()
{
: ${test=test}
_qname="$1"
eval "_qhead=\"\$_q${_qname}head\""
eval "_qtail=\"\$_q${_qname}tail\""
$test "$_qhead" = "$_qtail"
return $?
}
######################################################################
######################################################################
###
### File queue routines. The file queue is implemented as a file
### whose lines represent the queue elements. The file queue name
### is simply the file used for the queue, thus the use of multiple
### queues is allowed.
###
######################################################################
######################################################################
######################################################################
# init_fqueue name
# Initialize the named file queue.
######################################################################
init_fqueue()
{
_fqname="$1"
: > "$_fqname"
}
######################################################################
# append_fqueue name item ...
# Append items onto the end of the named file queue in FIFO order.
######################################################################
append_fqueue()
{
: ${echo=echo}
: ${test=test}
_fqname="$1"; shift
while $test $# -gt 0; do
$echo "$1" >> "$_fqname"
shift
done
}
######################################################################
# prepend_fqueue name item ...
# Prepend items to the head of the named file queue in LIFO order.
######################################################################
prepend_fqueue()
{
: ${cat=cat}
: ${echo=echo}
: ${mv=mv}
_fqname="$1"; shift
_fqtmpfile="$_fqname.$$"
init_queue _fqtmpqueue
prepend_queue _fqtmpqueue "$@"
while ! queue_is_empty _fqtmpqueue; do
pop_queue _fqtmpqueue _fqelt
$echo "$_fqelt" >> "$_fqtmpfile"
done
$cat "$_fqname" >> "$_fqtmpfile"
$mv -f "$_fqtmpfile" "$_fqname"
}
######################################################################
# head_fqueue name var
# Return the head of the named file queue in $var.
######################################################################
head_fqueue()
{
: ${head=head}
_fqname="$1"; shift
_tmp=`$head -n 1 "$_fqname"`
eval "${1}=\"\$_tmp\""
}
######################################################################
# pop_fqueue name var
# Pop off the head of the named file queue and return it in $var.
######################################################################
pop_fqueue()
{
: ${mv=mv}
: ${sed=sed}
_fqname="$1"; shift
_fqtmpfile="$_fqname.$$"
head_fqueue "$_fqname" $1
$sed "1,1d" "$_fqname" >> "$_fqtmpfile"
$mv -f "$_fqtmpfile" "$_fqname"
}
######################################################################
# fqueue_is_empty name
# Return 0 if the named file queue is empty and >0 otherwise.
######################################################################
fqueue_is_empty()
{
: ${test=test}
: ${wc=wc}
_fqname="$1"
if $test -f "$_fqname"; then
_fqlines=`$wc -l < "$_fqname"`
return $_fqlines
else
return 1
fi
}