3 # Purpose: Shellscript library
4 # Authors: grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
5 # Bug-Reports: see http://grml.org/bugs/
6 # License: This file is licensed under the GPL v2.
7 ################################################################################
9 . /usr/lib/grml/core.sh
15 # FIXME maybe PROG_PATH__ for better error reporting?
16 PROG_NAME__="" # initialised within init section
18 # directory for init scripts
19 INITD_DIR__="/etc/init.d/"
21 # >= level and the function will print the message
22 EPRINT__=1 # eprint (error print)
23 EEPRINT__=2 # 2print (intern error print)
24 DPRINT__=3 # dprint (debug print)
26 EXIT_FUNCTION__="_syslog" # function to call upon die (can be set by user)
32 LANGUAGE__="$LANGUAGE"
35 # CONFIG FUNCTIONS {{{
37 setProgName() { PROG_NAME__="$1"; }
39 setExitFunction() { EXIT_FUNCTION__="$1"; }
41 disableSyslog() { SYSLOG__="NO"; }
42 enableSyslog() { SYSLOG__="YES"; }
44 saveLang() { LANG__="$LANG"; LC_ALL__="$LC_ALL"; LANGUAGE__="$LANGUAGE"; }
45 restoreLang() { LANG="$LANG__"; LC_ALL="$LC_ALL__"; LANGUAGE="$LANGUAGE__"; }
46 setCLang() { saveLang; LANG="C"; LC_ALL="C"; LANGUAGE="C"; }
51 setVerbose() { VERBOSE__=${1:-1}; }
52 unsetVerbose() { VERBOSE_TMP__=$VERBOSE__; VERBOSE__=0; }
53 restoreVerbose() { VERBOSE__=$VERBOSE_TMP__; }
54 getVerbose() { echo "$VERBOSE__"; }
56 setDebug() { setVerbose "$DPRINT__"; }
57 unsetDebug() { restoreVerbose; }
59 setExitFunction() { EXIT_FUNCTION__="$1"; }
60 resetExitFunction() { EXIT_FUNCTION__="_syslog"; }
63 # ERROR REPORTING FUNCTIONS {{{
65 # default print backend (there may be other functions)
72 if [ "$VERBOSE__" -ge "$level_" -a -n "$message_" ]; then
81 # FIXME vprint should be a var, because we want to call user-defined functions
82 # global var (there should be a syslog, and vprint + syslog function)
83 vprint $EPRINT__ "Error - " "$1"
86 # should be used for intern silentExecutes
89 vprint $EEPRINT__ " Error2 - " "$1"
92 # print debug output (function intern errors)
95 vprint $DPRINT__ "Debug - " "$1"
98 # for program notice messages
101 vprint $EPRINT__ "Notice - " "$1"
106 local error_message_="$1" # print this error message
107 local exit_code_="$2" # command exited with this exit code
109 echo -n "PANIC: $error_message_" >&2
111 echo "; ret($exit_code_)" >&2
116 if [ -n "$EXIT_FUNCTION__" ]; then
117 $EXIT_FUNCTION__ "$error_message_" "$exit_code_" >&2
124 local error_message_="$1" # print this error message
125 local exit_code_="$2" # command exits with this exit code
127 echo -n "WARN: $error_message_" >&2
128 if [ -n "$exit_code_" ]; then
129 echo "; ret($exit_code_)" >&2
137 local message_="$1" # error message
138 local exit_code_="$2"
140 if [ "$SYSLOG__" = "YES" ]; then
141 if [ -n "$exit_code_" ]; then
142 logger -p user.alert -t "$PROG_NAME__" -i "$message_ ret($exit_code_)" >&2
144 logger -p user.alert -t "$PROG_NAME__" -i "$message_" >&2
151 local message_="$1" # error message
152 local exit_code_="$2"
154 if [ -n "$exit_code_" ]; then
155 logger -p user.alert -t "$PROG_NAME__" -i "$message_ ret($exit_code_)" >&2
157 logger -p user.alert -t "$PROG_NAME__" -i "$message_" >&2
163 local error_message_="$1" # print this error message
164 local exit_code_="$2" # command exits with this exit code
166 warn "$error_message_" "$exit_code_"
167 syslog "$error_message_" "$exit_code_"
174 # ATTENTION... THIS FUNCTION IS A BIG SECURITY HOLE
175 # this function will be changed in future release
177 # I don't want to write exit status control stuff every time
180 local to_exec_="$1" # command to execute
181 local error_function_=${2:-"eprint"} # function to call on error
182 local message_="$3" # user supplied error message
190 if [ $ret_ -eq 127 ]; then
191 syslog "problems executing ( $to_exec_ )" $ret_
193 if [ $ret_ -ne 0 ]; then
194 if [ -z "$message_" ]; then
195 $error_function_ "problems executing ( $to_exec_ )" "$ret_"
197 $error_function_ "$message_" "$ret_"
200 dprint "exec-$error_function_: ( $to_exec_ ) ret($ret_)"
220 # if the file DOES exist, everything is fine
223 local file_to_test_="$1" # file to test
224 local error_function_=${2:-"eprint"} # function to call on error
225 local message_="$3" # user supplied error message
227 if [ ! -e "$file_to_test_" ]; then
228 if [ -z "$message_" ]; then
229 $error_function_ "file does not exist \"$file_to_test_\"" 66
231 $error_function_ "$message_"
235 dprint "isExistent(): file \"$1\" does exist => ready to go"
241 local file_to_test_="$1" # file to test
242 local error_function_=${2:-"eprint"} # function to call on error
243 local message_="$3" # user supplied error message
245 if [ -e "$file_to_test_" ]; then
246 if [ -z "$message_" ]; then
247 $error_function_ "file does already exist \"$file_to_test_\"" 67
249 $error_function_ "$message_"
253 dprint "isNotExistent(): file \"$1\" does not exist => ready to go"
260 local to_check_="$1" # username to check against running process
261 local error_function_=${2:-"eprint"} # function to call on error
262 local message_="$3" # user supplied error message
267 if [ $user_ != "$to_check_" ]; then
268 if [ -z "$message_" ]; then
269 $error_function_ "username \"$user_\" is not \"$to_check_\"" 77 $exit_function_
271 $error_function_ "$message_"
275 dprint "checkUser(): accepted, username matches \"$to_check_\""
282 local to_check_="$1" # user-id to check against running process
283 local error_function_=${2:-"eprint"} # function to call on error
284 local message_="$3" # user supplied error message
289 if [ "$user_id_" != "$to_check_" ]; then
290 if [ -z "$message_" ]; then
291 $error_function_ "UID \"$user_id_\" is not \"$to_check_\"" 77
293 $error_function_ "$message_"
297 dprint "checkId(): accepted, UID matches \"$to_check_\""
309 if [ -f /etc/grml_version ] ; then
310 dprint "isGrml(): this seems to be a grml system"
313 dprint "isGrml(): this is not a grml system"
320 if [ -e "/etc/grml_cd" ]; then
321 dprint "runsFromHd(): grml is on CD"
324 dprint "runsFromHd(): grml is on HD"
331 if [ -e "/etc/grml_cd" ]; then
332 dprint "runsFromCd(): grml is on CD"
335 dprint "runsFromCd(): grml is on HD"
341 # secure input from console
344 local to_secure_="$1"
348 secured_=`echo -n "$to_secure_" |tr -c '[:alnum:]/.\-,\(\)' '_'`
349 dprint "secureInput(): \"$to_secure_\" => \"$secured_\""
354 # convert all possible path formats to absolute paths
360 abspath_="`readlink -f \"$relpath_\"`" || \
361 warn "relToAbs(): Problems getting absolute path" "$?" || return 1
362 dprint "relToAbs(): \"$relpath_\" => \"$abspath_\""
367 # Trim off white-space characters
368 # white-space in the "C" and "POSIX" locales are:
372 # carriage return ('\r')
373 # horizontal tab ('\t')
374 # vertical tab ('\v')
380 result_="`echo "$str_" | sed -e 's/^\s*//' -e 's/\s*$//'`" || \
381 warn "stringTrim(): Problems stripping of blanks" || return 1
382 dprint "stringTrim(): \"$str_\" => \"$result_\""
389 local to_test_="$1" # matching pattern
390 local source_="$2" # source-file to grep
392 if [ ! -e "$source_" ]; then
393 eprint "stringInFile(): \"$source_\" does not exist"
397 case "$(cat $source_)" in *$to_test_*) return 0;; esac
404 local to_test_="$1" # matching pattern
405 local source_="$2" # string to search in
407 case "$source_" in *$to_test_*) return 0;; esac
411 # get value for bootparam given as first param
418 # Check boot commandline for specified option
428 # validates an IP FIXME
431 local ip_="$1" # ip address to validate
432 local error_function_=${2:-"eprint"} # function to call on error
433 local message_="$3" # user supplied error message
437 echo "$ip_" | grep -E -q -e '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}' \
440 if [ $ret_ -ne 0 ]; then
441 if [ -z "$message_" ]; then
442 "$error_function_" "ip-address \"$ip_\" is NOT valid" $ret_
444 "$error_function_" "$message_" $ret_
449 dprint "ip-address \"$ip_\" is valid" $ret_
455 local error_function_=${1:-"eprint"} # function to call on error
456 local message_="$2" # user supplied error message
460 #ip a|grep 'inet ' |awk '$NF !~ /lo/{print $NF}'
461 if_="`ip a|grep 'inet ' |awk '{print $NF}'`"
463 if [ -z "$if_" ]; then
464 if [ -z "$message_" ]; then
465 "$error_function_" "no interfaces found" $ret_
467 "$error_function_" "$message_" $ret_
471 dprint "interfaces found" $ret_
476 netGetDefaultGateway()
478 local error_function_=${1:-"eprint"} # function to call on error
479 local message_="$2" # user supplied error message
485 ip_=`route -n | awk '/^0\.0\.0\.0/{print $2; exit}'`
488 if [ -z "$ip_" ]; then
489 if [ -z "$message_" ]; then
490 "$error_function_" "no default gateway found" $ret_
492 "$error_function_" "$message_" $ret_
496 dprint "default gateway is \"$ip_\"" $ret_
505 local error_function_=${2:-"eprint"} # function to call on error
506 local message_="$3" # user supplied error message
512 nm_=`ifconfig "$iface_" | awk '/[Mm]ask/{FS="[: ]*"; $0=$0; print $8; exit}'`
515 if [ -z "$nm_" ]; then
516 if [ -z "$message_" ]; then
517 "$error_function_" "could not find a netmask for \"$iface_\"" $ret_
519 "$error_function_" "$message_" $ret_
523 dprint "netmask on \"$iface_\" is \"$nm_\"" $ret_
532 local error_function_=${2:-"eprint"} # function to call on error
533 local message_="$3" # user supplied error message
539 #ip_=`ip addr list eth0 |mawk '/inet/{split($2,A,"/"); print A[1]}'`
540 ip_=`ifconfig "$iface_" | awk '/[Ii]net [Aa]ddr/{FS="[: ]*"; $0=$0; print $4; exit}'`
543 if [ -z "$ip_" ]; then
544 if [ -z "$message_" ]; then
545 "$error_function_" "no ip for \"$iface_\" found" $ret_
547 "$error_function_" "$message_" $ret_
551 dprint "address for \"$iface_\" is \"$ip_\"" $ret_
558 local error_function_=${1:-"eprint"} # function to call on error
559 local message_="$2" # user supplied error message
561 local file_="/etc/resolv.conf"
564 if [ ! -e $file_ ]; then
565 warn "file \"$file_\" does not exist, could not get nameservers"
570 ns_=`awk '/^nameserver/{printf "%s ",$2}' $file_ |xargs echo`
572 if [ -z "$ns_" ]; then
573 if [ -z "$message_" ]; then
574 "$error_function_" "no nameservers found" $ret_
576 "$error_function_" "$message_" $ret_
580 dprint "nameservers: \"$ns_\"" $ret_
590 local action_="${1:-"start"}"
592 local error_function_=${3:-"eprint"} # function to call on error
593 local message_="$4" # user supplied error message
596 local known_action_='false'
597 for i in "start" "stop" "restart" "reload" "force-reload"; do
598 if [ "$i" = "$action_" ]; then
603 $known_action_ || warn "_touchService(): unknown action \"$action_\""
606 local service_path_=""
607 service_path_="${INITD_DIR__}/$service_"
608 if [ ! -e "$service_path_" ]; then
609 warn "_touchService(): service does not exist: \"$service_\""
612 if [ ! -x "$service_path_" ]; then
613 warn "_touchService(): service is not executable: \"$service_\""
617 "$service_path_" "$action_"
619 if [ "$ret_" != "0" ]; then
620 if [ -z "$message_" ]; then
621 "$error_function_" "Problems ${action_}ing service \"$service_\"" $ret_
623 "$error_function_" "$message_" $ret_
627 dprint "_touchService(): successfully started service \"$service_\""
631 _createServiceFunctions()
633 for i in "start" "stop" "restart" "reload"; do
634 eval "${i}Service() { _touchService ${i} \"\$1\" \"\$2\" \"\$3\"; }"
636 eval "forceReloadService() { _touchService force-reload \"\$1\" \"\$2\" \"\$3\"; }"
638 _createServiceFunctions
641 # LOSETUP HELPER FUNCTION {{{
642 # print next free /dev/loop* to stdout
645 local error_function_=${1:-"eprint"} # function to call on error
646 local message_="$2" # user supplied error message
650 local ret_='' # saved return value
652 for i in 'losetup' 'losetup.orig'; do
653 tmp_=`$i -f 2>/dev/null`
654 if [ $? -eq 0 ]; then
661 dprint 'findNextFreeLoop(): losetup does not recognice option -f, searching next free loop device'
662 for i in `seq 0 100`; do
663 test -e /dev/loop$i || continue
664 losetup /dev/loop$i >/dev/null 2>&1
667 2) continue ;; # losetup could not get status of loopdevice (EPERM)
668 0) continue ;; # device exist
669 1) echo "/dev/loop$i"; return 0 ;; # device does not exist and no error
670 ?) continue ;; # return value not available in 'man losetup'
674 # hmm... could not find a loopdevice
675 if [ -z "$message_" ]; then
676 $error_function_ "could not find a free loop device"
678 $error_function_ "$message_"
688 local name_="$1" # program name
690 local tmp_name_=`basename "$name_"` || \
691 logger -p user.alert -i "Init-initProgName: problems executing ( basename \"$name_\" ) ret($?)" >/dev/null
693 secureInput "$tmp_name_"
695 PROG_NAME__=`_initProgName "$0"`
701 for i in tr dirname basename id logger kill cat grep route awk ifconfig; do
702 which $i >/dev/null 2>&1 || tmp_="${tmp_}$i "
704 if [ -n "$tmp_" ]; then
705 eprint "Init-checkExecutables: following executables not found or not executable:\n$tmp_"
706 #syslog "Init-checkExecutables: following executables not found or not executable: $tmp_"
714 # accept only integer as arguments
715 if echo "$DEBUG" | grep -E -q '^[0-9]+$' ; then
716 local debug_="${DEBUG:-0}"
726 ################################################################################
727 # vim:foldmethod=marker expandtab shiftwidth=2 tabstop=2