Make eerror() use '>&2' instead of '>/dev/stderr'
[grml-etc-core.git] / etc / grml / script-functions
1 # Filename:      /etc/grml/script-functions
2 # Purpose:       some often used functions for use in shellscripts
3 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
4 # Bug-Reports:   see http://grml.org/bugs/
5 # License:       This file is licensed under the GPL v2.
6 # Latest change: Tue, 23 Oct 2007 16:53:48 +0200 [ft]
7 ################################################################################
8
9 # {{{ set default PATH
10 setpath(){
11   export PATH=${PATH:-'/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin'}
12 }
13 # }}}
14
15 # {{{ check for root-permissions
16 check4root(){
17   if [ "$(id -u 2>/dev/null)" != 0 ] ; then
18     echo 1>&2 "Error: please run this script with uid 0 (root)." ; return 1
19   fi
20 }
21 # }}}
22
23 # {{{ check for user permissions
24 check4user(){
25   if [ "$(id -u 2>/dev/null)" = 0 ] ; then
26     echo 1>&2 "Error: please do not run this script with uid 0 (root)." ; return 1
27   fi
28 }
29 # }}}
30
31 # {{{ check for running zsh
32 iszsh(){
33   if ! [ -z "$ZSH_VERSION" ] ; then
34     return 0
35   else
36     return 1
37   fi
38 }
39 # }}}
40
41 # {{{ check for (X)dialog
42 setdialog(){
43   if [ -n "$DISPLAY" ] ; then
44      [ -x /usr/bin/Xdialog ] && DIALOG="Xdialog" && export XDIALOG_HIGH_DIALOG_COMPAT=1
45   else
46      [ -x /usr/bin/dialog ] && DIALOG='dialog' || ( echo 1>&2 "dialog not available" ; return 1 )
47   fi
48 }
49 # }}}
50
51 # {{{ check for availability of program(s)
52 check4progs(){
53   local RC=''
54   for arg in $* ; do
55     type -p $arg >/dev/null 2>&1 || RC="$arg"
56   done
57   if [ -n "$RC" ] ; then
58      echo "$RC not installed"
59      return 1
60   fi
61 }
62 # }}}
63
64 # {{{ simple shell grep
65 stringinfile(){
66   case "$(cat $2)" in *$1*) return 0;; esac
67   return 1
68 }
69 # }}}
70
71 # {{{ simple shell grep for strings
72 stringinstring(){
73   case "$2" in *$1*) return 0;; esac
74   return 1
75 }
76 # }}}
77
78 # {{{ reread boot command line; echo last parameter's argument or return false.
79 getbootparam(){
80   stringinstring " $1=" /proc/cmdline || return 1
81   result="${/proc/cmdline##*$1=}"
82   result="${result%%[   ]*}"
83   echo "$result"
84   return 0
85 }
86 # }}}
87
88 # {{{ check boot commandline for specified option
89 checkbootparam(){
90   stringinstring " $1" /proc/cmdline
91   return "$?"
92 }
93 # }}}
94
95 # {{{ check whether $1 is yes
96 checkvalue(){
97   if [ "$1" = "yes" -o "$1" = "YES" ] ; then
98     return 0
99   else
100     return 1
101   fi
102 }
103 # }}}
104
105 # {{{ grml specific checks
106 isgrml(){
107   [ -f /etc/grml_version ] && return 0 || return 1
108 }
109
110 grmlversion(){
111  cat /etc/grml_version
112 }
113
114 isgrmlcd(){
115   [ -f /etc/grml_cd ] && return 0 || return 1
116 }
117
118 isgrmlhd(){
119   [ -f /etc/grml_cd ] && return 1 || return 0
120 }
121
122 checkgrmlsmall(){
123   grep -q small /etc/grml_version 2>/dev/null && return 0 || return 1
124 }
125 # }}}
126
127 # {{{ filesystems (proc, pts, sys)
128 mount_proc(){
129   check4root || return 1
130   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
131 }
132
133 mount_pts(){
134   check4root || return 1
135   stringinfile "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
136 }
137
138 mount_sys(){
139   check4root || return 1
140   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
141 }
142 # }}}
143
144 # char *reverse_list(list) {{{
145 #
146 #   Returns the reversed order of list
147 #
148 reverse_list() {
149   local ret
150   ret=''
151   while [ "$#" -gt 0 ] ; do
152     if [ -z "${ret}" ] ; then
153       ret="$1"
154     else
155       ret="$1 ${ret}"
156     fi
157     shift
158   done
159   printf '%s' "${ret}"
160 }
161 #}}}
162
163 # bool is_older_than(reference, files/dirs to check) {{{
164 #
165 #   return 0 if any of the files/dirs are newer than
166 #   the reference file
167 #
168 #   EXAMPLE: if is_older_than a.out *.o ; then ...
169 is_older_than() {
170   local x
171   local ref="$1"
172   shift
173
174   for x in "$@" ; do
175     [ "${x}" -nt "${ref}" ] && return 0
176
177     if [ -d "${x}" ] ; then
178       is_older_than "${ref}" "${x}"/* && return 0
179     fi
180   done
181
182   return 1
183 }
184 #}}}
185
186 # e*() output functions {{{
187 # heavily based on gentoo's functions.sh; stripped down and modified
188 # to match our needs.
189 #
190 # defined functions:
191 #   ebegin()
192 #   eend()
193 #   eerror()
194 #   eindent()
195 #   einfo()
196 #   einfon()
197 #   eoutdent()
198 #   esetdent()
199 #   esyslog()
200 #   ewarn()
201 #   ewend()
202 #
203 # copyright 1999-2005 gentoo foundation
204 # distributed under the terms of the gnu general public license v2
205 # $header: /var/cvsroot/gentoo-src/rc-scripts/sbin/functions.sh,v 1.81.2.6 2005/05/15 20:00:31 vapier exp $
206
207 # initialisation {{{
208 # internal variables
209
210 # dont output to stdout?
211 rc_quiet_stdout="no"
212
213 # default values for e-message indentation and dots
214 rc_indentation=''
215 rc_default_indent=2
216 #rc_dot_pattern=' .'
217 rc_dot_pattern=''
218
219 # should we use color?
220 if [ -r /proc/cmdline ] ; then
221   grep -q ' nocolor' /proc/cmdline && RC_NOCOLOR='yes'
222 fi
223 [ -n "$NOCOLORS" ] && RC_NOCOLOR='yes'
224 RC_NOCOLOR="${RC_NOCOLOR:-no}"
225
226 # Can the terminal handle endcols?
227 RC_ENDCOL="yes"
228
229 # Setup COLS and ENDCOL so eend can line up the [ ok ]
230 # width of [ ok ] == 7
231 COLS="$(stty size 2>/dev/null | cut -d' ' -f2)"
232 if [ -z "${COLS}" ] || [ "${COLS}" -le 0 ] ; then
233   COLS=80
234 fi
235
236 if [ "${RC_ENDCOL}" = "yes" ]; then
237   ENDCOL="\e[A\e[$(( ${COLS} - 8 ))G"
238 else
239   ENDCOL=''
240 fi
241
242 # Setup the colors so our messages all look pretty
243 if [ "${RC_NOCOLOR}" = "yes" ]; then
244   unset GOOD WARN BAD NORMAL HILITE BRACKET
245 else
246   GOOD='\e[32;01m'
247   WARN='\e[33;01m'
248   BAD='\e[31;01m'
249   NORMAL='\e[0m'
250   HILITE='\e[36;01m'
251   BRACKET='\e[34;01m'
252 fi
253 #}}}
254
255 # void esyslog(char* priority, char* tag, char* message)
256 #
257 #    use the system logger to log a message
258 #
259 esyslog() {
260   local pri
261   local tag
262
263   [ "$#" -le 2 ] && return 0
264   if [ -x /usr/bin/logger ] ; then
265     pri="$1"
266     tag="$2"
267     shift 2
268
269     /usr/bin/logger -p "${pri}" -t "${tag}" -- "$@"
270   fi
271
272   return 0
273 }
274
275 # void eindent(int num)
276 #
277 #    increase the indent used for e-commands.
278 #
279 eindent() {
280   local i="${1:-0}"
281   [ "$i" -gt 0 ] || i="${RC_DEFAULT_INDENT}"
282   esetdent $(( ${#RC_INDENTATION} + $i ))
283 }
284
285 # void eoutdent(int num)
286 #
287 #    decrease the indent used for e-commands.
288 #
289 eoutdent() {
290   local i="${1:-0}"
291   [ "$i" -gt 0 ] || i="${RC_DEFAULT_INDENT}"
292   esetdent $(( ${#RC_INDENTATION} - $i ))
293 }
294
295 # void esetdent(int num)
296 #
297 #    hard set the indent used for e-commands.
298 #    num defaults to 0
299 #
300 esetdent() {
301   local i="${1:-0}"
302   [ "$i" -lt 0 ] && i=0
303   RC_INDENTATION="$(printf "%${i}s" '')"
304 }
305
306 # void einfo(char* message)
307 #
308 #    show an informative message (with a newline)
309 #
310 einfo() {
311   einfon "$*\n"
312   LAST_E_CMD=einfo
313   return 0
314 }
315
316 # void einfon(char* message)
317 #
318 #    show an informative message (without a newline)
319 #
320 einfon() {
321   [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
322   [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
323   printf " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
324   LAST_E_CMD=einfon
325   return 0
326 }
327
328 # void ewarn(char* message)
329 #
330 #    show a warning message + log it
331 #
332 ewarn() {
333   if [ "${RC_QUIET_STDOUT}" = "yes" ]; then
334       printf " $*\n"
335   else
336     [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
337     printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n"
338   fi
339
340   # Log warnings to system log
341   esyslog "daemon.warning" "rc-scripts" "$@"
342
343   LAST_E_CMD=ewarn
344   return 0
345 }
346
347 # void eerror(char* message)
348 #
349 #    show an error message + log it
350 #
351 eerror() {
352   if [ "${RC_QUIET_STDOUT}" = "yes" ]; then
353     printf " $*\n" >&2
354   else
355     [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo
356     printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n"
357   fi
358
359   # Log errors to system log
360   esyslog "daemon.err" "rc-scripts" "$@"
361
362   LAST_E_CMD=eerror
363   return 0
364 }
365
366 # void ebegin(char* message)
367 #
368 #    show a message indicating the start of a process
369 #
370 ebegin() {
371   local msg="$@" dots spaces
372   spaces="$(printf '%'"${#RC_DOT_PATTERN}"'s' '')"
373   [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
374
375   if [ -n "${RC_DOT_PATTERN}" ]; then
376     dots="$(printf "%$(( $COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')"
377     while [ "${dots#${spaces}}" != "${dots}" ] ; do
378         dots="${dots#${spaces}}${RC_DOT_PATTERN}"
379     done
380     msg="${msg}${dots}"
381   else
382     msg="${msg} ..."
383   fi
384   einfon "${msg}"
385   [ "${RC_ENDCOL}" = "yes" ] && echo
386
387   LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
388   LAST_E_CMD=ebegin
389   return 0
390 }
391
392 # void _eend(int error, char *efunc, char* errstr)
393 #
394 #    indicate the completion of process, called from eend/ewend
395 #    if error, show errstr via efunc
396 #
397 #    This function is private to functions.sh.  Do not call it from a
398 #    script.
399 #
400 _eend() {
401   local retval="${1:-0}" efunc="${2:-eerror}" msg
402   shift 2
403
404   if [ "${retval}" -eq 0 ]; then
405     [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0
406     msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
407   else
408     if [ "$#" -gt 0 ] ; then
409         "${efunc}" "$@"
410     fi
411     msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
412   fi
413
414   if [ "${RC_ENDCOL}" = "yes" ]; then
415     printf "${ENDCOL}  ${msg}\n"
416   else
417     [ "${LAST_E_CMD}" = "ebegin" ] || LAST_E_LEN=0
418     printf "%$(( ${COLS} - ${LAST_E_LEN} - 6 ))s%b\n" '' "${msg}"
419   fi
420
421   return "${retval}"
422 }
423
424 # void eend(int error, char* errstr)
425 #
426 #    indicate the completion of process
427 #    if error, show errstr via eerror
428 #
429 eend() {
430   local retval="${1:-0}"
431   shift
432
433   _eend "${retval}" eerror "$@"
434
435   LAST_E_CMD=eend
436   return "$retval"
437 }
438
439 # void ewend(int error, char* errstr)
440 #
441 #    indicate the completion of process
442 #    if error, show errstr via ewarn
443 #
444 ewend() {
445   local retval="${1:-0}"
446   shift
447
448   _eend "${retval}" ewarn "$@"
449
450   LAST_E_CMD=ewend
451   return "$retval"
452 }
453 #}}}
454
455 ## END OF FILE #################################################################
456 # vim:foldmethod=marker tw=80 ai expandtab shiftwidth=2 tabstop=2