d6513db226cee8c1dfad139356bcc8b381998185
[grml-etc-core.git] / etc / grml / lsb-functions
1 # lsb init-functions
2 #
3 # based on:
4 # /lib/lsb/init-functions for Debian -*- shell-script -*-
5 #
6 # Copyright (c) 2002-03 Chris Lawrence
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions
11 # are met:
12 # 1. Redistributions of source code must retain the above copyright
13 #    notice, this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 #    notice, this list of conditions and the following disclaimer in the
16 #    documentation and/or other materials provided with the distribution.
17 # 3. Neither the name of the author nor the names of other contributors
18 #    may be used to endorse or promote products derived from this software
19 #    without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # SUCH DAMAGE.
32
33 if [ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ] ; then
34   SYSTEMD=true
35 else
36   SYSTEMD=false
37 fi
38
39 # log_*() functions {{{
40 TPUT="${TPUT:-"/usr/bin/tput"}"
41
42 _have_tput() {
43     [ -x "$TPUT" ] && "$TPUT" hpa 60 >/dev/null 2>&1 \
44         && return 0 \
45         || return 1
46 }
47
48 log_success_msg() {
49     printf " * $@\n"
50 }
51
52 log_failure_msg() {
53     if _have_tput ; then
54         RED="$("$TPUT" setaf 1)"
55         #NORMAL="$("$TPUT" op)"
56         printf " ${RED}*${NORMAL} $@\n"
57     else
58         printf " * $@\n"
59     fi
60 }
61
62 log_warning_msg() {
63     if _have_tput ; then
64         YELLOW="$("$TPUT" setaf 3)"
65         #NORMAL="$("$TPUT" op")"
66         # printf " *${NORMAL} $@\n"
67         printf " ${BLUE}*${NORMAL} $@\n"
68     else
69         printf " * $@\n"
70     fi
71 }
72
73 log_warning_msg_nn() {
74     if _have_tput ; then
75         YELLOW="$("$TPUT" setaf 3)"
76         printf " ${BLUE}*${NORMAL} $@"
77     else
78         printf " * $@"
79     fi
80 }
81
82 # int log_begin_message (char *message)
83 log_begin_msg() {
84         if [ "$#" -eq 0 ]; then
85                 return 1
86         fi
87         printf " ${GREEN}*${NORMAL} $@\n"
88 }
89
90 log_begin_msg_nn() {
91         if [ "$#" -eq 0 ]; then
92                 return 1
93         fi
94         printf " ${GREEN}*${NORMAL} $@"
95 }
96
97
98 SUBMSG="   ${GREEN}-${NORMAL} "
99
100 # int log_end_message (int exitstatus)
101 log_end_msg() {
102
103     # If no arguments were passed, return
104     [ "$#" -eq 0 ] && return 1
105
106     # Only do the fancy stuff if we have an appropriate terminal
107     # and if /usr is already mounted
108     if _have_tput ; then
109         COLS="$("$TPUT" cols)"
110         if [ -n "$COLS" ]; then
111             COL=$(( $COLS - 7 ))
112         else
113             COL=73
114         fi
115         UP="$("$TPUT" cuu1)"
116         END="$("$TPUT" hpa "$COL")"
117         START="$("$TPUT" hpa 0)"
118         #RED="$("$TPUT" setaf 1)"
119         #NORMAL="$("$TPUT" op)"
120         if [ "$1" -eq 0 ]; then
121             printf "${UP}${END}${BLUE}[ ${GREEN}ok ${BLUE}]${NORMAL}\n"
122         else
123             printf "${UP}${START} ${RED}*${NORMAL}${END}[${RED}fail${NORMAL}]\n"
124         fi
125     else
126         if [ "$1" -eq 0 ]; then
127             printf "   ...done.\n"
128         else
129             printf "   ...fail!\n"
130         fi
131     fi
132     return "$1"
133 }
134 # }}}
135
136 # e*() output functions {{{
137 # heavily based on gentoo's functions.sh; stripped down and modified
138 # to match our needs.
139 #
140 # defined functions:
141 #   ebegin()
142 #   eend()
143 #   eerror()
144 #   eindent()
145 #   einfo()
146 #   einfon()
147 #   eoutdent()
148 #   esetdent()
149 #   esyslog()
150 #   ewarn()
151 #   ewend()
152 #
153 # copyright 1999-2005 gentoo foundation
154 # distributed under the terms of the gnu general public license v2
155 # $header: /var/cvsroot/gentoo-src/rc-scripts/sbin/functions.sh,v 1.81.2.6 2005/05/15 20:00:31 vapier exp $
156
157 # initialisation {{{
158 # internal variables
159
160 # Dont output to stdout?
161 RC_QUIET_STDOUT="no"
162
163 # Default values for e-message indentation and dots
164 RC_INDENTATION=''
165 RC_DEFAULT_INDENT=2
166 #RC_DOT_PATTERN=' .'
167 RC_DOT_PATTERN=''
168 # dont output to stdout?
169 rc_quiet_stdout="no"
170
171 # default values for e-message indentation and dots
172 rc_indentation=''
173 rc_default_indent=2
174 #rc_dot_pattern=' .'
175 rc_dot_pattern=''
176
177 # should we use color?
178 if [ -r /proc/cmdline ] ; then
179   grep -q ' nocolor' /proc/cmdline && RC_NOCOLOR='yes'
180 fi
181 [ -n "$NOCOLORS" ] && RC_NOCOLOR='yes'
182 RC_NOCOLOR="${RC_NOCOLOR:-no}"
183
184 # Can the terminal handle endcols?
185 if [ "${RC_NOCOLOR}" = "yes" ]; then
186   RC_ENDCOL="no"
187 else
188   RC_ENDCOL="yes"
189 fi
190
191 # Setup COLS and ENDCOL so eend can line up the [ ok ]
192 # width of [ ok ] == 7
193 COLS="$(stty size 2>/dev/null | cut -d' ' -f2)"
194 if [ -z "${COLS}" ] || [ "${COLS}" -le 0 ] ; then
195   COLS=80
196 fi
197
198 if [ "${RC_ENDCOL}" = "yes" ]; then
199   ENDCOL="\e[A\e[$(( ${COLS} - 8 ))G"
200 else
201   ENDCOL=''
202 fi
203
204 # Setup the colors so our messages all look pretty
205 if [ "${RC_NOCOLOR}" = "yes" ]; then
206   unset GOOD WARN BAD NORMAL HILITE BRACKET
207 else
208   GOOD='\e[32;01m'
209   WARN='\e[33;01m'
210   BAD='\e[31;01m'
211   NORMAL='\e[0m'
212   HILITE='\e[36;01m'
213   BRACKET='\e[34;01m'
214 fi
215 #}}}
216
217 # void esyslog(char* priority, char* tag, char* message)
218 #
219 #    use the system logger to log a message
220 #
221 esyslog() {
222   local pri
223   local tag
224
225   [ "$#" -le 2 ] && return 0
226   if [ -x /usr/bin/logger ] ; then
227     pri="$1"
228     tag="$2"
229     shift 2
230
231     /usr/bin/logger -p "${pri}" -t "${tag}" -- "$@"
232   fi
233
234   return 0
235 }
236
237 # void eindent(int num)
238 #
239 #    increase the indent used for e-commands.
240 #
241 eindent() {
242   local i="${1:-0}"
243   [ "$i" -gt 0 ] || i="${RC_DEFAULT_INDENT}"
244   esetdent $(( ${#RC_INDENTATION} + $i ))
245 }
246
247 # void eoutdent(int num)
248 #
249 #    decrease the indent used for e-commands.
250 #
251 eoutdent() {
252   local i="${1:-0}"
253   [ "$i" -gt 0 ] || i="${RC_DEFAULT_INDENT}"
254   esetdent $(( ${#RC_INDENTATION} - $i ))
255 }
256
257 # void esetdent(int num)
258 #
259 #    hard set the indent used for e-commands.
260 #    num defaults to 0
261 #
262 esetdent() {
263   local i="${1:-0}"
264   [ "$i" -lt 0 ] && i=0
265   RC_INDENTATION="$(printf "%${i}s" '')"
266 }
267
268 # void einfo(char* message)
269 #
270 #    show an informative message (with a newline)
271 #
272 einfo() {
273   einfon "$*\n"
274   LAST_E_CMD=einfo
275   return 0
276 }
277
278 # void einfon(char* message)
279 #
280 #    show an informative message (without a newline)
281 #
282 einfon() {
283   [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
284   [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
285   printf " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
286   LAST_E_CMD=einfon
287   return 0
288 }
289
290 # void ewarn(char* message)
291 #
292 #    show a warning message + log it
293 #
294 ewarn() {
295   if [ "${RC_QUIET_STDOUT}" = "yes" ]; then
296       printf " $*\n"
297   else
298     [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
299     printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n"
300   fi
301
302   # Log warnings to system log
303   esyslog "daemon.warning" "rc-scripts" "$@"
304
305   LAST_E_CMD=ewarn
306   return 0
307 }
308
309 # void eerror(char* message)
310 #
311 #    show an error message + log it
312 #
313 eerror() {
314   if [ "${RC_QUIET_STDOUT}" = "yes" ]; then
315     printf " $*\n" >&2
316   else
317     [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
318     printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n"
319   fi
320
321   # Log errors to system log
322   esyslog "daemon.err" "rc-scripts" "$@"
323
324   LAST_E_CMD=eerror
325   return 0
326 }
327
328 # void ebegin(char* message)
329 #
330 #    show a message indicating the start of a process
331 #
332 ebegin() {
333   local msg="$@" dots spaces
334   spaces="$(printf '%'"${#RC_DOT_PATTERN}"'s' '')"
335   [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
336
337   if [ -n "${RC_DOT_PATTERN}" ]; then
338     dots="$(printf "%$(( $COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')"
339     while [ "${dots#${spaces}}" != "${dots}" ] ; do
340         dots="${dots#${spaces}}${RC_DOT_PATTERN}"
341     done
342     msg="${msg}${dots}"
343   else
344     msg="${msg} ..."
345   fi
346   einfon "${msg}"
347   [ "${RC_ENDCOL}" = "yes" ] && echo
348
349   LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
350   LAST_E_CMD=ebegin
351   return 0
352 }
353
354 # void _eend(int error, char *efunc, char* errstr)
355 #
356 #    indicate the completion of process, called from eend/ewend
357 #    if error, show errstr via efunc
358 #
359 #    This function is private to functions.sh.  Do not call it from a
360 #    script.
361 #
362 _eend() {
363   local retval="${1:-0}" efunc="${2:-eerror}" msg
364   shift 2
365
366   if [ "${retval}" -eq 0 ]; then
367     [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
368     msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
369   else
370     if [ "$#" -gt 0 ] ; then
371         "${efunc}" "$@"
372     fi
373     msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
374   fi
375
376   if [ "${RC_ENDCOL}" = "yes" ]; then
377     printf "${ENDCOL}  ${msg}\n"
378   else
379     [ "${LAST_E_CMD}" = "ebegin" ] || LAST_E_LEN=0
380     printf "%$(( ${COLS} - ${LAST_E_LEN} - 6 ))s%b\n" '' "${msg}"
381   fi
382
383   return "${retval}"
384 }
385
386 # void eend(int error, char* errstr)
387 #
388 #    indicate the completion of process
389 #    if error, show errstr via eerror
390 #
391 eend() {
392   local retval="${1:-0}"
393   shift
394
395   _eend "${retval}" eerror "$@"
396
397   LAST_E_CMD=eend
398   return "$retval"
399 }
400
401 # void ewend(int error, char* errstr)
402 #
403 #    indicate the completion of process
404 #    if error, show errstr via ewarn
405 #
406 ewend() {
407   local retval="${1:-0}"
408   shift
409
410   _eend "${retval}" ewarn "$@"
411
412   LAST_E_CMD=ewend
413   return "$retval"
414 }
415 #}}}
416
417 # if we're using systemd then redfine functions for
418 # output in systemd style
419 if $SYSTEMD ; then
420   einfo() {
421     printf "[  ${GREEN}OK${NORMAL}  ] %s\n" "$*"
422   }
423
424   ewarn() {
425     printf "[ ${YELLOW}WARN${NORMAL} ] %s\n" "$*"
426   }
427
428   eerror() {
429     printf "[ ${RED}FAIL${NORMAL} ] %s\n" "$*"
430   }
431
432   eend() {
433     :
434   }
435 fi
436
437 # don't expose unneeded local variables
438 unset SYSTEMD
439
440 # vim: ft=sh tw=80 ts=4 foldmethod=marker