Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/libexec/rc/hooks.sh
34821 views
1
:
2
# NAME:
3
# hooks.sh - provide hooks for customization
4
#
5
# SYNOPSIS:
6
# hooks_add_all HOOKS [--first] func [...]
7
# hooks_add_once HOOKS [--first] func [...]
8
# hooks_add_default_set {all,once}
9
# hooks_add HOOKS func [...]
10
# hooks_get [--lifo] HOOKS
11
# hooks_run [--lifo] HOOKS ["args"]
12
# hooks_run_all [--lifo] HOOKS ["args"]
13
# hooks_has HOOKS func
14
#
15
# add_hooks HOOKS [--first] func [...]
16
# run_hooks HOOKS [LIFO] ["args"]
17
# run_hooks_all HOOKS [LIFO] ["args"]
18
#
19
# DESCRIPTION:
20
# The functions add_hooks and run_hooks are retained for
21
# backwards compatibility. They are aliases for hooks_add and
22
# hooks_run.
23
#
24
# hooks_add_all simply adds the "func"s to the list "HOOKS".
25
#
26
# If the first arg is '--first' "func"s are added to the start
27
# of the list.
28
#
29
# hooks_add_once does the same but only if "func" is not in "HOOKS".
30
# hooks_add uses one of the above based on "option", '--all' (default)
31
# or '--once'.
32
#
33
# hooks_add_default_set sets the default behavior of hooks_add
34
#
35
# hooks_get simply returns the named list of functions.
36
#
37
# hooks_has indicates whether "func" in in "HOOKS".
38
#
39
# hooks_run runs each "func" in $HOOKS and stops if any of them
40
# return a bad status.
41
#
42
# hooks_run_all does the same but does not stop on error.
43
#
44
# If run_hooks or run_hooks_all is given a flag of '--lifo' or
45
# 2nd argument of LIFO the hooks are run in the reverse order of
46
# calls to hooks_add.
47
# Any "args" specified are passed to each hook function.
48
#
49
50
# RCSid:
51
# $Id: hooks.sh,v 1.26 2025/08/07 21:59:54 sjg Exp $
52
#
53
# @(#)Copyright (c) 2000-2024 Simon J. Gerraty
54
#
55
# SPDX-License-Identifier: BSD-2-Clause
56
#
57
# Please send copies of changes and bug-fixes to:
58
# [email protected]
59
#
60
61
# avoid multiple inclusion
62
_HOOKS_SH=:
63
64
# does local *actually* work?
65
local_works() {
66
local _fu
67
}
68
69
if local_works > /dev/null 2>&1; then
70
_local=local
71
else
72
_local=:
73
fi
74
# for backwards compatability
75
local=$_local
76
77
78
##
79
# hooks_add_all list func ...
80
#
81
# add "func"s to "list" regardless
82
#
83
hooks_add_all() {
84
eval $_local __h
85
__h=$1; shift
86
case "$1" in
87
--first)
88
shift
89
eval "$__h=\"$* \$$__h\""
90
;;
91
*) eval "$__h=\"\$$__h $*\"";;
92
esac
93
}
94
95
##
96
# hooks_add_once list func ...
97
#
98
# add "func"s to "list" if not already there
99
#
100
hooks_add_once() {
101
eval $_local __h __hh __first
102
__h=$1; shift
103
case "$1" in
104
--first) shift; __first=:;;
105
*) __first=;;
106
esac
107
eval "__hh=\$$__h"
108
while [ $# -gt 0 ]
109
do
110
: __hh="$__hh" 1="$1"
111
case "$__first $__hh " in
112
*" $1 "*) ;; # dupe
113
:*) __hh="$1 $__hh";;
114
*) __hh="$__hh $1";;
115
esac
116
shift
117
done
118
eval "$__h=\"$__hh\""
119
}
120
121
##
122
# hooks_add_default_set [--]{all,once}
123
#
124
# change the default method of hooks_add
125
#
126
hooks_add_default_set() {
127
case "$1" in
128
once|--once) HOOKS_ADD_DEFAULT=once;;
129
*) HOOKS_ADD_DEFAULT=all;;
130
esac
131
}
132
133
##
134
# hooks_add [--{all,once}] list func ...
135
#
136
# add "func"s to "list"
137
#
138
# If '--once' use hooks_add_once,
139
# default is hooks_add_all.
140
#
141
hooks_add() {
142
case "$1" in
143
--all) shift; hooks_add_all "$@";;
144
--once) shift; hooks_add_once "$@";;
145
*) hooks_add_${HOOKS_ADD_DEFAULT:-all} "$@";;
146
esac
147
}
148
149
##
150
# hooks_get [--lifo] list [LIFO]
151
#
152
# return $list
153
#
154
hooks_get() {
155
eval $_local __h __h2 e __l
156
case "$1" in
157
--lifo) __l=LIFO; shift;;
158
esac
159
eval "__h=\$$1"
160
case "$__l$2" in
161
LIFO*)
162
__h2="$__h"
163
__h=
164
for e in $__h2
165
do
166
__h="$e $__h"
167
done
168
;;
169
esac
170
echo "$__h"
171
}
172
173
##
174
# hooks_has list func
175
#
176
# is func in $list ?
177
#
178
hooks_has() {
179
eval $_local __h
180
eval "__h=\$$1"
181
case " $__h " in
182
*" $1 "*) return 0;;
183
esac
184
return 1
185
}
186
187
##
188
# hooks_run [--all] [--lifo] list [LIFO] [args]
189
#
190
# pass "args" to each function in "list"
191
# Without '--all'; if any return non-zero return that immediately
192
#
193
hooks_run() {
194
eval $_local __a e __h __hl __h2 __l
195
__a=return
196
__l=
197
198
while :
199
do
200
case "$1" in
201
--all) __a=:; shift;;
202
--lifo) __l=$1; shift;;
203
*) break;;
204
esac
205
done
206
__hl=$1; shift
207
case "$1" in
208
LIFO) __l=--lifo; shift;;
209
esac
210
__h=`hooks_get $__l $__hl`
211
for e in $__h
212
do
213
$e "$@" || $__a $?
214
done
215
}
216
217
##
218
# hooks_run_all [--lifo] list [LIFO] [args]
219
#
220
# pass "args" to each function in "list"
221
#
222
hooks_run_all() {
223
hooks_run --all "$@"
224
}
225
226
##
227
# add_hooks,run_hooks[_all] aliases
228
#
229
add_hooks() {
230
hooks_add "$@"
231
}
232
233
run_hooks() {
234
hooks_run "$@"
235
}
236
237
run_hooks_all() {
238
hooks_run --all "$@"
239
}
240
241
242
case /$0 in
243
*/hooks.sh)
244
# simple unit-test
245
list=HOOKS
246
flags=
247
while :
248
do
249
: 1=$1
250
case "$1" in
251
HOOKS|*hooks) list=$1; shift;;
252
--*) flags="$flags $1"; shift;;
253
*) break;;
254
esac
255
done
256
for f in "$@"
257
do
258
: f=$f
259
case "$f" in
260
LIFO) ;;
261
false|true) ;;
262
*) eval "$f() { echo This is $f; }";;
263
esac
264
done
265
echo hooks_add $flags $list "$@"
266
hooks_add $flags $list "$@"
267
echo hooks_run $list
268
hooks_run $list
269
echo hooks_run --all --lifo $list
270
hooks_run --all --lifo $list
271
echo hooks_run $list LIFO
272
hooks_run $list LIFO
273
;;
274
esac
275
276