# lsb init-functions # vim:ft=sh:tw=80 # /lib/lsb/init-functions for Debian -*- shell-script -*- # # Copyright (c) 2002-03 Chris Lawrence # All rights reserved. # # 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. # 3. Neither the name of the author nor the names of other contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. TPUT="${TPUT:-"/usr/bin/tput"}" have_tput() { [ -x "$TPUT" ] && "$TPUT" hpa 60 >/dev/null 2>&1 \ && return 0 \ || return 1 } log_success_msg () { printf " * $@\n" } log_failure_msg () { if have_tput ; then RED="$("$TPUT" setaf 1)" #NORMAL="$("$TPUT" op)" printf " ${RED}*${NORMAL} $@\n" else printf " * $@\n" fi } log_warning_msg () { if have_tput ; then YELLOW="$("$TPUT" setaf 3)" #NORMAL="$("$TPUT" op")" # printf " *${NORMAL} $@\n" printf " ${BLUE}*${NORMAL} $@\n" else printf " * $@\n" fi } log_warning_msg_nn () { if have_tput ; then YELLOW="$("$TPUT" setaf 3)" printf " ${BLUE}*${NORMAL} $@" else printf " * $@" fi } # int log_begin_message (char *message) log_begin_msg () { if [ "$#" -eq 0 ]; then return 1 fi printf " ${GREEN}*${NORMAL} $@\n" } log_begin_msg_nn () { if [ "$#" -eq 0 ]; then return 1 fi printf " ${GREEN}*${NORMAL} $@" } SUBMSG=" ${GREEN}-${NORMAL} " # int log_end_message (int exitstatus) log_end_msg () { # If no arguments were passed, return [ "$#" -eq 0 ] && return 1 # Only do the fancy stuff if we have an appropriate terminal # and if /usr is already mounted if have_tput ; then COLS="$("$TPUT" cols)" if [ -n "$COLS" ]; then COL=$(( "$COLS" - 7 )) else COL=73 fi UP="$("$TPUT" cuu1)" END="$("$TPUT" hpa $COL)" START="$("$TPUT" hpa 0)" #RED="$("$TPUT" setaf 1)" #NORMAL="$("$TPUT" op)" if [ "$1" -eq 0 ]; then printf "${UP}${END}${BLUE}[ ${GREEN}ok ${BLUE}]${NORMAL}\n" else printf "${UP}${START} ${RED}*${NORMAL}${END}[${RED}fail${NORMAL}]\n" fi else if [ "$1" -eq 0 ]; then printf " ...done.\n" else printf " ...fail!\n" fi fi return "$1" } # Copyright 1999-2005 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-src/rc-scripts/sbin/functions.sh,v 1.81.2.6 2005/05/15 20:00:31 vapier Exp $ RC_GOT_FUNCTIONS="yes" # Different types of dependencies deptypes="need use" # Different types of order deps ordtypes="before after" # # Internal variables # # Dont output to stdout? RC_QUIET_STDOUT="no" RC_VERBOSE="${RC_VERBOSE:-no}" # Should we use color? if [ -r /proc/cmdline ] ; then grep -q ' nocolor' /proc/cmdline && RC_NOCOLOR='yes' fi RC_NOCOLOR="${RC_NOCOLOR:-no}" # Can the terminal handle endcols? RC_ENDCOL="yes" # # Default values for rc system # RC_TTY_NUMBER=11 RC_NET_STRICT_CHECKING="no" RC_PARALLEL_STARTUP="no" RC_USE_CONFIG_PROFILE="yes" # # Default values for e-message indentation and dots # RC_INDENTATION='' RC_DEFAULT_INDENT=2 #RC_DOT_PATTERN=' .' RC_DOT_PATTERN='' # void splash(...) # # Notify bootsplash/splashutils/gensplash/whatever about # important events. # splash() { return 0 } # void profiling(...) # # Notify bootsplash/whatever about important events. # profiling() { return 0 } # void get_bootconfig() # # Get the BOOTLEVEL and SOFTLEVEL by setting # 'bootlevel' and 'softlevel' via kernel # parameters. # get_bootconfig() { local copt= local newbootlevel= local newsoftlevel= for copt in $( 0 )) || (( i = RC_DEFAULT_INDENT )) esetdent $(( ${#RC_INDENTATION} + i )) } # void eoutdent(int num) # # decrease the indent used for e-commands. # eoutdent() { local i=$1 (( i > 0 )) || (( i = RC_DEFAULT_INDENT )) esetdent $(( ${#RC_INDENTATION} - i )) } # void esetdent(int num) # # hard set the indent used for e-commands. # num defaults to 0 # esetdent() { local i=$1 (( i < 0 )) && (( i = 0 )) RC_INDENTATION=$(printf "%${i}s" '') } # void einfo(char* message) # # show an informative message (with a newline) # einfo() { einfon "$*\n" LAST_E_CMD=einfo return 0 } # void einfon(char* message) # # show an informative message (without a newline) # einfon() { [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0 [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo printf " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*" LAST_E_CMD=einfon return 0 } # void ewarn(char* message) # # show a warning message + log it # ewarn() { if [ "${RC_QUIET_STDOUT}" = "yes" ]; then printf " $*\n" else [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n" fi # Log warnings to system log esyslog "daemon.warning" "rc-scripts" "$*" LAST_E_CMD=ewarn return 0 } # void eerror(char* message) # # show an error message + log it # eerror() { if [ "${RC_QUIET_STDOUT}" = "yes" ]; then printf " $*\n" >/dev/stderr else [ "${RC_ENDCOL}" != "yes" ] && [ "${LAST_E_CMD}" = "ebegin" ] && echo printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n" fi # Log errors to system log esyslog "daemon.err" "rc-scripts" "$*" LAST_E_CMD=eerror return 0 } # void ebegin(char* message) # # show a message indicating the start of a process # ebegin() { local msg="$*" dots spaces spaces="$(printf '%'"${#RC_DOT_PATTERN}"'s' '')" [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0 if [ -n "${RC_DOT_PATTERN}" ]; then dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '') while [ "${dots#${spaces}}" != "${dots}" ] ; do dots="${dots#${spaces}}${RC_DOT_PATTERN}" done msg="${msg}${dots}" else msg="${msg} ..." fi einfon "${msg}" [ "${RC_ENDCOL}" = "yes" ] && echo LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} )) LAST_E_CMD=ebegin return 0 } # void _eend(int error, char *efunc, char* errstr) # # indicate the completion of process, called from eend/ewend # if error, show errstr via efunc # # This function is private to functions.sh. Do not call it from a # script. # _eend() { local retval=${1:-0} efunc=${2:-eerror} msg shift 2 if [ "${retval}" -eq 0 ]; then [ "${RC_QUIET_STDOUT}" = "yes" ] && return 0 msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}" else if [ -n "$*" ]; then "${efunc}" "$*" fi msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}" fi if [ "${RC_ENDCOL}" = "yes" ]; then printf "${ENDCOL} ${msg}\n" else [ "${LAST_E_CMD}" = "ebegin" ] || LAST_E_LEN=0 printf "%$(( "${COLS}" - "${LAST_E_LEN}" - 6 ))s%b\n" '' "${msg}" fi return ${retval} } # void eend(int error, char* errstr) # # indicate the completion of process # if error, show errstr via eerror # eend() { local retval=${1:-0} shift _eend ${retval} eerror "$*" LAST_E_CMD=eend return $retval } # void ewend(int error, char* errstr) # # indicate the completion of process # if error, show errstr via ewarn # ewend() { local retval=${1:-0} shift _eend ${retval} ewarn "$*" LAST_E_CMD=ewend return $retval } # v-e-commands honor RC_VERBOSE which defaults to no. # The condition is negated so the return value will be zero. veinfo() { [ "${RC_VERBOSE}" != yes ] || einfo "$@"; } veinfon() { [ "${RC_VERBOSE}" != yes ] || einfon "$@"; } vewarn() { [ "${RC_VERBOSE}" != yes ] || ewarn "$@"; } veerror() { [ "${RC_VERBOSE}" != yes ] || eerror "$@"; } vebegin() { [ "${RC_VERBOSE}" != yes ] || ebegin "$@"; } veend() { [ "${RC_VERBOSE}" = "yes" ] && { eend "$@"; return $?; } return ${1:-0} } veend() { [ "${RC_VERBOSE}" = "yes" ] && { ewend "$@"; return $?; } return ${1:-0} } # char *KV_major(string) # # Return the Major (X of X.Y.Z) kernel version # KV_major() { [ -z "$1" ] && return 1 local KV=$@ printf "${KV%%.*}\n" } # char *KV_minor(string) # # Return the Minor (Y of X.Y.Z) kernel version # KV_minor() { [ -z "$1" ] && return 1 local KV="$@" KV="${KV#*.}" printf "${KV%%.*}\n" } # char *KV_micro(string) # # Return the Micro (Z of X.Y.Z) kernel version. # KV_micro() { [ -z "$1" ] && return 1 local KV="$@" KV="${KV#*.*.}" printf "${KV%%[^[:digit:]]*}\n" } # int KV_to_int(string) # # Convert a string type kernel version (2.4.0) to an int (132096) # for easy compairing or versions ... # KV_to_int() { [ -z "$1" ] && return 1 local KV_MAJOR="$(KV_major "$1")" local KV_MINOR="$(KV_minor "$1")" local KV_MICRO="$(KV_micro "$1")" local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO )) # We make version 2.2.0 the minimum version we will handle as # a sanity check ... if its less, we fail ... if [ "${KV_int}" -ge 131584 ] ; then printf "${KV_int}\n" return 0 fi return 1 } # int get_KV() # # Return the kernel version (major, minor and micro concated) as an integer. # Assumes X and Y of X.Y.Z are numbers. Also assumes that some leading # portion of Z is a number. # e.g. 2.4.25, 2.6.10, 2.6.4-rc3, 2.2.40-poop, 2.0.15+foo # get_KV() { local KV="$(uname -r)" printf "$(KV_to_int "${KV}")\n" return $? } # bool get_bootparam(param) # # return 0 if gentoo=param was passed to the kernel # # EXAMPLE: if get_bootparam "nodevfs" ; then .... # get_bootparam() { local x copt params retval=1 [ ! -r "/proc/cmdline" ] && return 1 for copt in $(< /proc/cmdline) do if [ "${copt%=*}" = "gentoo" ] then params="$(gawk -v PARAMS="${copt##*=}" ' BEGIN { split(PARAMS, nodes, ",") for (x in nodes) print nodes[x] }')" # Parse gentoo option for x in ${params} do if [ "${x}" = "$1" ] then # printf "YES\n" retval=0 fi done fi done return ${retval} } # Safer way to list the contents of a directory, # as it do not have the "empty dir bug". # # char *dolisting(param) # # print a list of the directory contents # # NOTE: quote the params if they contain globs. # also, error checking is not that extensive ... # dolisting() { local x= local y= local tmpstr= local mylist= local mypath="$*" if [ "${mypath%/\*}" != "${mypath}" ] then mypath="${mypath%/\*}" fi for x in ${mypath} do [ ! -e "${x}" ] && continue if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] ) then mylist="${mylist} $(ls "${x}" 2> /dev/null)" else [ "${x%/}" != "${x}" ] && x="${x%/}" cd "${x}"; tmpstr="$(ls)" for y in ${tmpstr} do mylist="${mylist} ${x}/${y}" done fi done printf "${mylist}\n" } # char *add_suffix(char * configfile) # # Returns a config file name with the softlevel suffix # appended to it. For use with multi-config services. add_suffix() { if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -e "$1.${DEFAULTLEVEL}" ] then printf "$1.${DEFAULTLEVEL}\n" else printf "$1\n" fi return 0 } # Network filesystems list for common use in rc-scripts. # This variable is used in is_net_fs and other places such as # localmount. NET_FS_LIST="afs cifs coda gfs ncpfs nfs nfs4 shfs smbfs" # bool is_net_fs(path) # # return 0 if path is the mountpoint of a networked filesystem # # EXAMPLE: if is_net_fs / ; then ... # is_net_fs() { local fstype # /proc/mounts is always accurate but may not always be available if [ -e /proc/mounts ]; then fstype="$( sed -n -e '/^rootfs/!s:.* '"$1"' \([^ ]*\).*:\1:p' /proc/mounts )" else fstype="$( mount | sed -n -e 's:.* on '"$1"' type \([^ ]*\).*:\1:p' )" fi case " ${NET_FS_LIST} " in *" ${fstype} "*) return 0 ;; *) return 1 ;; esac } # bool is_uml_sys() # # return 0 if the currently running system is User Mode Linux # # EXAMPLE: if is_uml_sys ; then ... # is_uml_sys() { grep -qs 'UML' /proc/cpuinfo return $? } # bool is_vserver_sys() # # return 0 if the currently running system is a Linux VServer # # EXAMPLE: if is_vserver_sys ; then ... # is_vserver_sys() { grep -qs '^s_context:[[:space:]]*[1-9]' /proc/self/status return $? } # bool get_mount_fstab(path) # # return the parameters to pass to the mount command generated from fstab # # EXAMPLE: cmd=$( get_mount_fstab /proc ) # cmd=${cmd:--t proc none /proc} # mount -n ${cmd} # get_mount_fstab() { awk '$1 ~ "^#" { next } $2 == "'$*'" { if (found++ == 0) { print "-t "$3,"-o "$4,$1,$2 } } END { if (found > 1) { print "More than one entry for '$*' found in /etc/fstab!" > "/dev/stderr" } } ' /etc/fstab } # char *reverse_list(list) # # Returns the reversed order of list # reverse_list() { local ret ret='' while [ "$#" -gt 0 ] ; do if [ -z "${ret}" ] ; then ret="$1" else ret="$1 ${ret}" fi shift done printf '%s' "${ret}" } # bool is_older_than(reference, files/dirs to check) # # return 0 if any of the files/dirs are newer than # the reference file # # EXAMPLE: if is_older_than a.out *.o ; then ... is_older_than() { local x local ref="$1" shift for x in "$@" ; do [ "${x}" -nt "${ref}" ] && return 0 if [ -d "${x}" ] ; then is_older_than "${ref}" "${x}"/* && return 0 fi done return 1 } # Setup a basic $PATH. Just add system default to existing. # This should solve both /sbin and /usr/sbin not present when # doing 'su -c foo', or for something like: PATH= rcscript start PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:${PATH}" if [ "$(/sbin/consoletype 2> /dev/null)" = "serial" ] ; then # We do not want colors/endcols on serial terminals RC_NOCOLOR="yes" RC_ENDCOL="no" fi for arg in "$@" ; do case "${arg}" in # Lastly check if the user disabled it with --nocolor argument --nocolor|-nc) RC_NOCOLOR="yes" ;; esac done # Setup COLS and ENDCOL so eend can line up the [ ok ] # width of [ ok ] == 7 COLS="$(stty size 2>/dev/null | cut -d' ' -f2)" if [ -z "${COLS}" ] || [ "${COLS}" -le 0 ] ; then COLS=80 fi if [ "${RC_ENDCOL}" = "yes" ]; then ENDCOL="[$(( ${COLS} - 8 ))G" else ENDCOL='' fi # Setup the colors so our messages all look pretty if [ "${RC_NOCOLOR}" = "yes" ]; then unset GOOD WARN BAD NORMAL HILITE BRACKET else GOOD='' WARN='' BAD='' NORMAL='' HILITE='' BRACKET='' fi # vim:ts=4