# lsb init-functions {{{ # /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. log_success_msg () { echo " * $@" } log_failure_msg () { TPUT=/usr/bin/tput if [ -x $TPUT ] && $TPUT hpa 60 >/dev/null 2>&1; then RED=`$TPUT setaf 1` #NORMAL=`$TPUT op` echo " ${RED}*${NORMAL} $@" else echo " * $@" fi } log_warning_msg () { TPUT=/usr/bin/tput if [ -x $TPUT ] && $TPUT hpa 60 >/dev/null 2>&1; then YELLOW=`$TPUT setaf 3` #NORMAL=`$TPUT op` # echo " *${NORMAL} $@" echo " ${BLUE}*${NORMAL} $@" else echo " * $@" fi } log_warning_msg_nn () { TPUT=/usr/bin/tput if [ -x $TPUT ] && $TPUT hpa 60 >/dev/null 2>&1; then YELLOW=`$TPUT setaf 3` echo -n " ${BLUE}*${NORMAL} $@" else echo -n " * $@" fi } # int log_begin_message (char *message) log_begin_msg () { if [ -z "$1" ]; then return 1 fi echo " ${GREEN}*${NORMAL} $@" } log_begin_msg_nn () { if [ -z "$1" ]; then return 1 fi echo -n " ${GREEN}*${NORMAL} $@" } SUBMSG=" ${GREEN}-${NORMAL} " # int log_end_message (int exitstatus) log_end_msg () { # If no arguments were passed, return [ -z "$1" ] && return 1 # Only do the fancy stuff if we have an appropriate terminal # and if /usr is already mounted TPUT=/usr/bin/tput EXPR=/usr/bin/expr if [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1; then COLS=`$TPUT cols` if [ -n "$COLS" ]; then COL=`$EXPR $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 echo "$UP$END${BLUE}[ ${GREEN}ok ${BLUE}]${NORMAL}" else echo -e "${UP}${START} ${RED}*${NORMAL}${END}[${RED}fail${NORMAL}]" fi else if [ $1 -eq 0 ]; then echo " ...done." else echo " ...fail!" fi fi return $1 } # void esyslog(char* priority, char* tag, char* message) # use the system logger to log a message #esyslog() { # local pri= # local tag= # # if [ -x /usr/bin/logger ] # then # pri="$1" # tag="$2" # # shift 2 # [[ -z "$*" ]] && return 0 # # /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*" # fi # # return 0 #} # 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? 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 echo -ne " ${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 echo " $*" else [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}$*" 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 echo " $*" >/dev/stderr else [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}$*" 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=${RC_DOT_PATTERN//?/ } [[ ${RC_QUIET_STDOUT} == yes ]] && return 0 if [[ -n ${RC_DOT_PATTERN} ]]; then dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '') dots=${dots//${spaces}/${RC_DOT_PATTERN}} 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} == 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 echo -e "${ENDCOL} ${msg}" 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=$@ echo ${KV%%.*} } # char *KV_minor(string) # # Return the Minor (Y of X.Y.Z) kernel version # KV_minor() { [[ -z $1 ]] && return 1 local KV=$@ KV=${KV#*.} echo ${KV%%.*} } # char *KV_micro(string) # # Return the Micro (Z of X.Y.Z) kernel version. # KV_micro() { [[ -z $1 ]] && return 1 local KV=$@ KV=${KV#*.*.} echo ${KV%%[^[:digit:]]*} } # 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 echo "${KV_int}" 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) echo $(KV_to_int "${KV}") 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 # echo "YES" 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 echo "${mylist}" } # 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 echo "$1.${DEFAULTLEVEL}" else echo "$1" 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 [[ " ${NET_FS_LIST} " == *" ${fstype} "* ]] return $? } # 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() { for (( i = $# ; i > 0 ; --i )); do echo -n "${!i} " done } # 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 } if [ -z "${EBUILD}" ] ; then # 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 else # Should we use colors ? if [[ $* != *depend* ]]; then # Check user pref in portage RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)" [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes" else # We do not want colors during emerge depend RC_NOCOLOR="yes" # No output is seen during emerge depend, so this is not needed. RC_ENDCOL="no" fi fi if [[ -n ${EBUILD} && $* == *depend* ]]; then # We do not want stty to run during emerge depend COLS=80 else # Setup COLS and ENDCOL so eend can line up the [ ok ] COLS=${COLUMNS:-0} # bash's internal COLUMNS variable (( COLS == 0 )) && COLS=$(stty size 2>/dev/null | cut -d' ' -f2) (( COLS > 0 )) || (( COLS = 80 )) # width of [ ok ] == 7 fi if [[ ${RC_ENDCOL} == yes ]]; then ENDCOL=$'\e[A\e['$(( COLS - 7 ))'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=$'\e[32;01m' WARN=$'\e[33;01m' BAD=$'\e[31;01m' NORMAL=$'\e[0m' HILITE=$'\e[36;01m' BRACKET=$'\e[34;01m' fi # vim:ts=4 # }}}