#!/bin/bash
###############################################################################
# #
# F01 common.lib : A library for common functions. #
# This library should work with KSH93 & BASH. #
# #
# +---------------------------------------------------------------------+ #
# | Copyright (c) 2009-2015 Flyounet | #
# +---------------------------------------------------------------------+ #
# | This program is free software: you can redistribute it and/or | #
# | modify it under the terms of the GNU General Public License as | #
# | published by the Free Software Foundation, either version 3 of the | #
# | License, or (at your option) any later version. | #
# | | #
# | This program is distributed in the hope that it will be useful, | #
# | but WITHOUT ANY WARRANTY; without even the implied warranty of | #
# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | #
# | GNU General Public License for more details. | #
# | | #
# | You should have received a copy of the GNU General Public License | #
# | along with this program. | #
# | If not, see . | #
# +---------------------------------------------------------------------+ #
# | Cette œuvre est distribuée SANS AUCUNE GARANTIE hormis celle d'être | #
# | distribuée sous les termes de la License Demerdez-vous ("Demerden | #
# | Sie Sich License") plus communément appelée DSSL telle que publiée | #
# | par Flyounet : soit la version 1 de cette licence, soit (à votre | #
# | gré) toute version ultérieure. | #
# | | #
# | Vous devriez avoir reçu une copie de la Licence Démerdez-vous avec | #
# | cette œuvre ; si ce n’est pas le cas, consultez : | #
# | . | #
# +---------------------------------------------------------------------+ #
# | Author: Flyounet < dev @@ flyounet . net > | #
# +---------------------------------------------------------------------+ #
# #
###############################################################################
# #
# v0.01 [20/01/2009] Flyounet [@Home] : #
# > Initiale Release (from myEasyConnect script) #
# v0.07 [20/11/2009] Flyounet [@Home] : #
# + Rewriting code to be more readable and a really lib. #
# v0.08 [23/11/2009] Flyounet [@Work] : #
# + Add Comments and header. #
# > If you need to Debug set the variable below to a value > 0 #
# eg. 5 if you want the function call and 6 if you also want the exit #
# v0.09 [23/11/2009] Flyounet [@Work] : #
# + iniParseFile & iniGetValue : To parse INI files #
# v0.10 [23/11/2009] Flyounet [@Work] : #
# * p2s : add the -- before string to avoid problem #
# v0.12 [23/11/2009] Flyounet [@Home] : #
# * Force the DEBUG to var 0 if not set #
# v0.12 [23/11/2009] Flyounet [@Home] : #
# * myDebug: I forget to print the Debug level #
# * myDebug: It was a problem of shift before print #
# v0.13 [23/11/2009] Flyounet [@Work] : #
# * fileCheck : Typo problem in a test #
# v0.14 [23/11/2009] Flyounet [@Home] : #
# * iniParseFile: Change of the awk matchString. #
# v0.16 [23/11/2009] Flyounet [@Home] : #
# + logMe, LogMeV, logRotate : Logs Functions #
# v0.17 [25/11/2009] Flyounet [@Home] : #
# * Correct the 3 last function added. #
# v0.19 [27/11/2009] Flyounet [@Home] : #
# + isFunction: Return 1/0 if the arg is function Name. #
# v0.20 [02/12/2009] Flyounet [@Home] : #
# + sprintf: Equivalent to C sprintf function. #
# + isFunction: Now with a second arg can detect a programme or function#
# v0.21 [22/01/2010] Flyounet [@Home] : #
# * trim: As I want a shell lib, I comment the usage of sed and let the #
# shell version by using variables. #
# + ltrim & rtrim: left trim & right trim of [[:space:]] in shell. #
# * trim: Now use ltrim & rtrim instead of builtin and sed. #
# > Adding [@Home] and [@Work] to know where I work on this lib. #
# v0.22 [??/01/2010] Flyounet [@Home] : #
# > Can't remember what have been done. #
# v0.23 [30/01/2010] Flyounet [@Home] : #
# * fileCreate: In case of error during touch an ugly message is now #
# sent to /dev/null (for chmod too) #
# v0.24 [03/03/2010] Flyounet [@Home] : #
# > First svn version #
# v0.25 [01/04/2010] Flyounet [@Home] : #
# + textFill: equivalent to perl "string" x number #
# + textBox: put a caracter all around a text #
# * textBox: not working with KSH #
# + _str2lower & _str2upper have been added, cause to KSH that doesn't #
# support Case modification of Bash. #
# * textBox: now use _str2*er and work with KSH #
# * iniGetValue: Remove the call to awk (Yeah ! Love shell !) #
# v0.26 [22/04/2010] Flyounet [@Home] : #
# + parseHeadersForHelp: Print the headers of each function in a file. #
# Headers are based on a first line containing a #F??. #
# > textBox: Only works with KSH... Fuck ! #
# * textBox: A subfile is needed to make it works with bash. #
# v0.27 [27/04/2010] Flyounet [@Home] : #
# > Problem with the Bash version. If old Bash is use BASH_SOURCE #
# doesn't exist... #
# Now looks for the files instead of trying to load it directly to #
# avoid, error messages. Search in above and under directory. #
# * F01Version return the path of the Bash extension. #
# * trim : Huge bug ! Instead of unsetting __ltrim & __trim, i unsetted #
# functions ltrim & rtrim... #
# > ltrim & rtrim don't work under Bash ! ARGGGGGGGGGGGGG !!!!! #
# * iniParseFile : In case of a line only containing a left var with #
# incorrect character (like a dash -), the awk version sent an error #
# to the output (and under Ksh stops). #
# Function has been rewritted purely in shell... #
# * sprintf : Problem under Bash. Bash doesn't support only one _ as a #
# variable name : Corrected. #
# * iniGetValue : Not use grep anymore. Only Shell ! #
# * fileCheck : Problem under Bash. Bash doesn't support only one _ as #
# a variable name : Corrected. #
# * logMe : Problem under Bash. Bash doesn't support only one _ as a #
# variable name : Corrected. #
# > Now only logRotate use non-shell programs ! #
# + myError : If none args then empty __lastError #
# v0.28 [03/05/2010] Flyounet [@Home] : #
# + statusBar : generate the informations to have a status bar (eg. #
# 0%....5%....10%.... and so on until 100% #
#- * statusBar : Change the call during the myDebug(6) #
# v0.29 [05/01/2011] Flyounet [@Home] : #
# + Change scripts to use include instead of prereqs #
# * statusBar : If function is called multiple time with a 0, it's #
# printed until th evalue change... #
# * p2s : Forced to use the builtin shell printf function. #
# * isFunction Forced to use the builtin shell command function. #
# * fileDelete & fileCreate : add a -- (double dash) in case of a weird #
# filename containing dash.... #
# + randomString : exists to generate pseudorandom strings #
# * parseHeadersForHelp: Insensitive search added. #
# + _p2s : print to screen without new line #
# * p2s : now call _p2s instead of the builtin printf #
# * Change some writing with ]; then and ohter ; do #
# > It's the birthday of the husband of my sister... #
# v0.30 [03/05/2011] Flyounet [@Home] : #
# > Lots of modifications, since I discover a problem with string #
# containing % (percent symbol) in case of use of p2s. #
# + _p2sp & p2sp : they are able to deal with strings containing % and #
# should be preffered to _p2s & p2s when you are sure about the #
# text you use. #
# * myDebug, logMe & others functions have been changed to use p2sp #
# instead of p2s #
# + I'm in the process of replacing sprintf by sprintfv2 but preliminary#
# tests show sprintf is 50% faster than the v2 (but can't handle %i #
# or %.2f, etc) like sprintfv2. #
# > Need to import change from unstable/F01common.lib_v0.30* branche. #
# > Import Start #
# + Add 3 booleans : FALSE, TRUE & NULL. #
# * Replace all exit status and return code by the Boolean. #
# * I replace 'which' by 'command -v', it seems less slow than 'which', #
# more independant as no external 'which' needed. #
# * logRotate : remove the awk for wc -l... #
# * oops & oopst could return another value than one if var set before #
# * __bash & __ksh are set to TRUE when working Shell is discovered #
# - logMe, logMeV, logRotate have been moved in the F04logger.lib #
# > logMe, logMeV, logRotate not removed for the time being #
# * TRUE & FALSE are now 0 & 1 #
# > Protocol updated due to result of function returned. #
# * myDebug Force the use of __utsCmd. If possible date is faster than #
# perl. #
# * _p2s : beurk, I really dislike this hack. #
# > End of import #
# * [lr]trimv2 created #
# + __zsh is set to TRUE when ZSH discovered. Starting to test ZSH. #
# + _e2s & e2s are 2 new function to use echo instead of printf when #
# needed. #
# v0.31 [28/02/2012] Flyounet [@Home] : #
# * _p2sp : Under AIX when searching for %, return the end of string. #
# Changed the //%/%% to //\%/%% #
# * All command -v calls are followed by 2>/dev/null :) #
# > It's important to note that it will never work with KSH88 !!! The #
# default KSH used on AIX... :) #
# * textFill : Default Value affectation error... & forget to use the #
# _pattern variable... #
# * rtrim: an error could appear during execution... Corrected with #
# the new test F01.19 :) #
# * ltrim: an error could appear during execution... Corrected with #
# the new test F01.18 :) #
# * isFunction : Modified error Message & the call with 'builtin' if #
# under Ksh... builtin command -v --> command commnd -v #
# + isNum : return true/false if the value is numeric or not. #
# * testFill: if 3rd arg equal to TRUE, don't break the pattern to 1car #
# + missingCommands : Exit if one command is missing (#22) #
# + err2s(p) : Print message to stderr #
# + _ltrim & _rtrim take a variable name instead of data. (#64) #
# + _trim takes variable name instead of data. #
# * __*sh are set to false and then to true. (#66) #
# * missingCommands check if runnig onAIX to avoid stats check. (#67) #
# * myDebug: prints messages to standard error. #
# * logMe: Change the __ variable by __logme to avoid some strange #
# behaviour under bash. When calling p2sp a double \n append. #
# * fileCreate: I just replace touch by >. #
# * If F01DEBUG is already set before the load of lib, it's lost ! #
# Now, if already setted, the value is not lost ! #
# * if __MYDEBUG is not defined, it's defined to 9. This variable is #
# used to force the level at which the Debug is printed. #
# * _p2sp: Internal change to avoid some conflict with exported __ vars.#
# v0.32 [06/02/2015] Flyounet [@Home] : #
# * Removing some old comments. #
# + The checking part of the fileCheck function is FROZEN (and probably #
# removed in the future, as not enough reliable). #
# > fileCheck : Comments added about frozen zone #
# + myDebug: If F01DEBUG @ 9 and in Bash mode, Stack Trace of function #
# is added in the line printed. #
# + getPidParent : To have the parent of the PID #
# + getPidParents : To have the parents of the PID #
# + getPidSons : To have all the Sons (and little sons) of the PID #
# + getPidFamily : To have all Parents & sons of the PID #
# * This versino was the last that support Ksh & Bash. The future #
# version will only support Bash. #
# v0.50 [??/??/2015] Flyounet [@Home] : #
# * Merging external Bash extension #
# * Removing Log Functions #
# * Removing unused functions #
# #
# #
F01VERSION=0.50
F01PROTOCOL=0.04
###############################################################################
# #
# Todo : #
# < iniGetValue and iniParseFile need an extra argument or a global variable #
# to separate keyName and valueName. By default use :: #
# <- rtrim & ltrim to be modified to only take variable name. #
# <- trim to use new ltrim & rtrim #
# < If the IFS is change before a call to myDebug,there is prb with date... #
# #
###############################################################################
# #
# Legende : #
# + --> Indique une nouveaute, un ajout de fonctionnalite. #
# * --> Indique une correction de bogue. #
# - --> Indique la suppression d'une fonctionnalite/variable. #
# > --> Indique une information n'ayant pas forcement de rapport avec le code#
# < --> Indique une amelioration a apporter au code. #
# <- --> Indique une amelioration en cours de developpement/realisation. #
# OK --> Indique qu'une amelioration a ete effectuee. #
# #
###############################################################################
# ############################################################################ #
# Functions
# ############################################################################ #
#F01.00.06
#Function : _p2s(p), Print to screen (percent) string passed in argument
#Syntaxe : _p2s(p)
#Return : nothing
#Notes :
_p2s() {
[[ ${__bash} -eq ${TRUE} ]] && builtin printf -- "${@}" || command printf -- "${@}"
}
_p2sp() {
typeset __p2sp__="${@}"; _p2s "${__p2sp__//\%/%%}"
}
#F01.01.05
#Function : p2s(p), Print to screen (percent) string passed in argument (with an end of line)
#Syntaxe : p2s(p)
#Return : nothing
#Notes :
p2s() {
_p2s "${@}\n"
}
p2sp() {
_p2sp "${@}\n"
}
#F01.02.02
#Function : p2st, Print to screen string passed in argument, with Time before
#Syntaxe : p2st
#Return : nothing
#Notes :
p2st() {
p2s "$(date '+%F %T')\n${@}"
}
#F01.03.02
#Function : oops, Print to screen string passed in argument, and exit 1
#Syntaxe : oops
#Return : nothing
#Notes : if __oops setted return __oops
oops() {
p2s "${@}" >&2
exit ${__oops:=1}
}
#F01.04.02
#Function : oopst, Print to screen string passed in argument, with time before, and exit 1
#Syntaxe : oopst
#Return : nothing
#Notes : if __oopst setted return __oopst
oopst() {
p2st "${@}" >&2
exit ${__oopst:=1}
}
#F01.05.11
#Function : myDebug, Print to screen string passed in argument if debug level is reach
#Syntaxe : myDebug
#Return : nothing
#Notes : Dependent of __bash, F01DEBUG, F01STRACE
myDebug() {
if [ ${F01DEBUG:=0} -ge ${1} ]; then
_debug="--\033[01;31mDEBUG\033[0m(\033[01;32m${1}\033[0m)----"
shift
if [ ${__bash} -eq ${TRUE} -a ${F01DEBUG} -eq 9 -a ${F01STRACE:=$TRUE} -eq ${TRUE} ]; then
#_debug="${_debug}[$( ${__utsCmd} )][$(date '+%d/%m/%Y %H%M%S' )]--\033[02;37m${BASH_LINENO}-$( set -- "${FUNCNAME[@]}"; shift; echo ${@})\033[0m-${@}"
_debug="${_debug}[$( ${__utsCmd} )][$(date '+%d/%m/%Y %H%M%S' )]--${@}--\033[02;37m$(set -- "${FUNCNAME[@]}"; shift 2; echo ${@})\033[0m"
else
_debug="${_debug}[$( ${__utsCmd} )][$(date '+%d/%m/%Y %H%M%S' )]----${@}"
fi
p2sp "${_debug}" >&2
fi
}
#F01.06.03
#Function : myError, Store error in variables
#Syntaxe : myError
#Return : nothing
#Notes : Store last error in var __lastError and all errors in __allError
myError() {
myDebug ${__MYDEBUG} "myError(${@})"
export __lastError="${@}"
if [ ! -z "${@}" ]; then
export __allError="[$(date '+%d/%m/%Y %H%M%S' )]${@}\n${__allError}"
fi
}
#F01.07.05
#Function : fileCheck, Check file for presence and permission
#Syntaxe : fileCheck []
#Return : 1=OK [fileName exists and permission are ok], 0=Fail
#Notes :
fileCheck() {
myDebug ${__MYDEBUG} "fileCheck(${@})"
if [ -z "${1}" ]; then
myError "fileCheck: Filename is empty"
return ${FALSE}
fi
if [ ! -f "${1}" ]; then
myError "fileCheck: File doesn't exists are is not a file"
return ${FALSE}
fi
###### Cette partie est FROZEN ! DEBUT #####
if [ ! -z "${2}" ]; then
if [ ${__cmdSTAT} -eq 0 ]; then
myError "fileCheck: Command 'stat' is not available"
return ${FALSE}
fi
__=$( stat -c'%a' "${1}" )
if [ "${__}" = "${2}" -o "${__}" = "0${2}" ]; then
return ${TRUE}
else
myError "fileCheck: Rights error [${__} instead of ${2}]"
return ${FALSE}
fi
fi
###### Cette partie est FROZEN ! FIN #####
return ${TRUE}
}
#F01.08.05
#Function : fileCreate, Create file with permissions if asked
#Syntaxe : fileCreate []
#Return : 0=OK [fileName exists and permission are ok], 1=Fail
#Notes :
fileCreate() {
myDebug ${__MYDEBUG} "fileCreate(${@})"
if [ -z "${1:-}" ]; then
myError "fileCreate: Filename is empty"
return ${FALSE}
fi
#touch -- "${1}" 2>/dev/null
(> "${1}") 2>/dev/null
if [ $? -ne 0 ]; then
myError "fileCreate: Can't touch file"
return ${FALSE}
fi
if [ ! -z "${2:-}" ]; then
chmod ${2} "${1}" 2>/dev/null
if [ $? -ne 0 ]; then
myError "fileCreate: Can't chmod"
return ${FALSE}
fi
fi
return ${TRUE}
}
#F01.09.02
#Function : fileDelete, Delete the specified file
#Syntaxe : fileDelete
#Return : 1=OK [fileName exists and permission are ok], 0=Fail
#Notes :
fileDelete() {
myDebug ${__MYDEBUG} "fileDelete(${@})"
if [ -z "${1}" ]; then
myError "fileDelete: Filename is empty"
return ${FALSE}
fi
rm -f -- "${1}"
if [ $? -ne 0 ]; then
myError "fileDelete: Can't remove file"
return ${FALSE}
fi
return ${TRUE}
}
#F01.10.06
#Function : iniGetValue, Get the value from a specified INI file
#Syntaxe : iniGetValue []
#Return : 1=OK, 0=Fail
#Notes : Default way of working is to set __iniGetValue. If the third arg is
# set the is set with the result.
iniGetValue() {
myDebug ${__MYDEBUG} "iniGetValue(${@})"
fileCheck "${1}"
if [ $? -ne ${TRUE} ]; then
return ${FALSE}
fi
if [ -z "${2}" ]; then
myError "iniGetValue: Variable name is empty"
return ${FALSE}
fi
_findValue=0
while read _line; do
if [ "x${_line//*$2*::*/$2}x" = "x${2}x" ]; then
ltrim "${_line}"
if [ "${__ltrim:0:1}" != '#' ]; then
rtrim "${__ltrim%%::*}"
_lvar="${__rtrim}"
trim "${_line#*::}"
#let _findValue=${_findValue}+1
(( _findValue=${_findValue}+1 ))
if [ ${_findValue} -gt 1 ]; then
myError "iniGetValue: Variable name found more than once"
return ${FALSE}
fi
fi
fi
done < "${1}"
if [ ${_findValue} -eq 0 ]; then
myError "iniGetValue: Variable name not found"
return ${FALSE}
fi
export __iniGetValue="${__trim}"
if [ ! -z ${3} ]; then
if [ "x${_lvar//[_a-zA-Z0-9]/}x" = "xx" -a "${_lvar: -1}" != "_" -a "${_lvar}" != "_" -a "${_lvar}" != "__" ]; then
eval "export ${_lvar}='${__iniGetValue}'"
else
myError "iniGetValue: Variable name is unsafe to be set !"
return ${FALSE}
fi
fi
return ${TRUE}
}
#F01.11.06
#Function : iniParseFile, Set all values from a specified INI file
#Syntaxe : iniParseFile
#Return : 1=OK, 0=Fail
#Notes : All non commented variables are setted if they are valid
# : variable name MUST be in the Followinf Format :
# : _?_?[0-9a-zA-Z][_0-9a-zA-Z]*[^_]
iniParseFile() {
myDebug ${__MYDEBUG} "iniParseFile(${@})"
if [ -z "${1}" ]; then
myError "iniParseFile: Filename is empty"
return ${FALSE}
fi
_nbExportedVars=0
while read _line; do
if [ ! -z "${_line}" -a "x${_line//*::*/::}x" = "x::x" ]; then
ltrim "${_line}"
if [ "${__ltrim:0:1}" != '#' ]; then
rtrim "${_line%%::*}"
_lvar="${__rtrim}"
if [ "x${_lvar//[_a-zA-Z0-9]/}x" = "xx" -a "${_lvar: -1}" != "_" -a "${_lvar}" != "_" -a "${_lvar}" != "__" ]; then
trim "${_line#*::}"
eval "export ${_lvar}='${__trim}'"
(( _nbExportedVars=${_nbExportedVars}+1 ))
fi
fi
fi
done < "${1}"
return ${_nbExportedVars}
}
#F01.12a.01
#Function : _trim, Remove all blank from begining and end
#Syntaxe : _trim
#Return : N/A
#Notes : Get data from Variable Name given as Arguement and re-set this variable
# : All catacters \t, \n, \r and space are removed.
_trim() {
myDebug ${__MYDEBUG} "_trim(${@})"
__="${1}"
_ltrim "${1}"
_rtrim "${1}"
unset __
}
#F01.12b.05
#Function : trim, Remove all blank from begining and end
#Syntaxe : trim
#Return : 1=OK
#Notes : export the trimmed variable in __trim.
# : All catacters \t, \n, \r and space are removed.
# : If we had use sed : __trim=$( sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' <<<"${@}" )
trim() {
myDebug ${__MYDEBUG} "trim(${@})"
__trim="${@}"
_trim "__trim"
return ${TRUE}
}
#F01.13.05
#Function : logRotate, Transfer the begining of a file to the rotationned version.
#Syntaxe : logRotate
#Return : 1=OK, 0=Fail
#Notes : Log rotation couldn't be under 10 lines
#Notes : The rotated log file are suffixed by the date of day.
logRotate() {
myDebug ${__MYDEBUG} "logRotate(${@})"
fileCheck "${1}"
if [ ${?} -ne ${TRUE} ]; then
myError "logRotate: can't find logfile"
return ${FALSE}
fi
if [ -z "${2}" -o ${2:-0} -lt 10 ]; then
_maxLine=10
else
_maxLine=${2}
fi
_lines=$( wc -l < "${1}" )
(( _linesToDrop=${_lines}-${_maxLine}+1 ))
if [ ${_lines} -gt ${_maxLine} ]; then
head -${_linesToDrop} "${1}" >> "${1}.$( date '+%Y%m%d' )"
if [ $? -ne 0 ]; then
myError "logRotate: can't transfer head lines"
return ${FALSE}
fi
sed -i "1,${_linesToDrop}d" "${1}"
if [ $? -ne 0 ]; then
myError "logRotate: can't delete head lines"
return ${FALSE}
fi
fi
return ${TRUE}
}
#F01.14.06
#Function : logMe, Send the log to the log files
#Syntaxe : logMe
#Return : 1=OK
#Notes : Even if the log fail, it returns 1
#Notes : Log are systematically rotated before writting.
#Notes : Log are systematically sent into the verbose log.
#Notes : Variables __cmdPERL, __logVerbose, __logDir, __logFile, __logFileV,
# __logFileSize, __logFileVSize must be defined before the call.
logMe() {
myDebug ${__MYDEBUG} "logMe(${@})"
typeset __logme="[$( ${__utsCmd} )][$(date '+%d/%m/%Y %H%M%S' )] --> ${@}"
if [ -z "${__logVerbose}" ]; then
logRotate "${__logDir}/${__logFile}" ${__logFileSize}
p2sp "${__logme}" >> "${__logDir}/${__logFile}"
fi
logRotate "${__logDir}/${__logFileV}" ${__logFileVSize}
p2sp "${__logme}" >> "${__logDir}/${__logFileV}"
return ${TRUE}
}
#F01.15.01
#Function : logMeV, Send the log to the verbose log files
#Syntaxe : logMeV
#Return : 1=OK
#Notes : Even if the log fail, it returns 1
logMeV() {
myDebug ${__MYDEBUG} "logMeV(${@})"
export __logVerbose=1
logMe "${@}"
unset __logVerbose
return ${TRUE}
}
#F01.16.07
#Function : isFunction, Verify that the function exists
#Syntaxe : isFunction [<1>]
#Return : 1=OK, 0=Fail
#Notes : Set the 2nd arg to check either programme or function
isFunction() {
myDebug ${__MYDEBUG} "isFunction(${@})"
if [ -z "${1}" ]; then
myError "isFunction: Function name is empty"
return ${FALSE}
fi
__="$([[ ${__bash} -eq ${TRUE} ]] && builtin command -v "${1}" 2>/dev/null || command command -v "${1}" 2>/dev/null)"
if [ "${1}" = "${__}" ]; then
return ${TRUE}
elif [ ! -z "${2}" ]; then
if [ "${1}" = "${__##*/}" ]; then
return ${TRUE}
else
myError "isFunction: Function name, builtin or programme is unknown"
return ${FALSE}
fi
else
myError "isFunction: Function name or builtin is unknown"
return ${FALSE}
fi
}
#F01.17.08
#Function : sprintf, return a formatted string
#Syntaxe : sprintf
#Return : 1=OK
#Notes : __sprintf contains the result of the sprintf call
sprintf() {
myDebug ${__MYDEBUG} "sprintf(${@})"
__=${#}
__sprintf="${1}"
shift
i=1
while [ $i -ne ${__} ]; do
__sprintf="${__sprintf%%%s*}${1}${__sprintf#*%s}"
#let i=$i+1
(( i=$i+1 ))
shift
done
export __sprintf
return ${TRUE}
}
sprintfv2() {
myDebug ${__MYDEBUG} "sprintfv2(${@})"
_tmp="${1}"
shift
export ${_tmp}="$(_p2s "${@}" 2>/dev/null)"
return ${TRUE}
}
#F01.18b.01
#Function : _ltrim, Remove all blank from begining
#Syntaxe : _ltrim
#Return : N/A
#Notes : Get data from Variable Name given as Arguement and re-set this variable
# : All catacters \t, \n, \r and space are removed.
_ltrim () {
myDebug ${__MYDEBUG} "_ltrim(${@})"
if [ -z "${1:-}" ]; then
myError "_ltrim: Variable name empty"
elif [ ${__bash} -eq ${TRUE} -a "x${__BASH_EXTENSION}" = 'xloaded' ]; then
_ltrimBash "${@}"
else
eval _local="\${${1}}"
if [ ! -z "${_local}" ]; then
while [ "x${_local:0:1}" = "x " -o "x${_local:0:1}" = "x " -o "x${_local:0:1}" = "x\n" -o "x${_local:0:1}" = "x\r" -o "x${_local:0:1}" = 'x
' ]; do
_local="${_local:1}"
done
eval export "${1}"='${_local}'
unset _local
fi
fi
}
#F01.18a.06
#Function : ltrim, Remove all blank from begining
#Syntaxe : ltrim
#Return : 1=OK
#Notes : export the ltrimmed variable in __ltrim
# : All catacters \t, \n, \r and space are removed.
ltrim() {
myDebug ${__MYDEBUG} "ltrim(${@})"
__ltrim="${@}"
_ltrim "__ltrim"
return ${TRUE}
}
#F01.19b.01
#Function : _rtrim, Remove all blank from end
#Syntaxe : _rtrim
#Return : N/A
#Notes : Get data from Variable Name given as Arguement and re-set this variable
# : All catacters \t, \n, \r and space are removed.
_rtrim () {
myDebug ${__MYDEBUG} "_rtrim(${@})"
if [ -z "${1:-}" ]; then
myError "_rtrim: Variable name empty"
elif [ ${__bash} -eq ${TRUE} -a "x${__BASH_EXTENSION}" = 'xloaded' ]; then
_rtrimBash "${@}"
else
eval _local="\${${1}}"
if [ ! -z "${_local}" ]; then
while [ "x${_local: -1}" = "x " -o "x${_local: -1}" = "x " -o "x${_local: -1}" = "x\n" -o "x${_local: -1}" = "x\r" -o "x${_local: -1}" = 'x
' ]; do
#let __=${#_local}-1
(( __=${#_local}-1 ))
_local="${_local:0:$__}"
done
eval export "${1}"='${_local}'
unset _local
fi
fi
}
#F01.19a.05
#Function : rtrim, Remove all blank from end
#Syntaxe : rtrim
#Return : 1=OK
#Notes : export the rtrimmed variable in __rtrim
# : All catacters \t, \n, \r and space are removed.
rtrim() {
myDebug ${__MYDEBUG} "rtrim(${@})"
__rtrim="${@}"
_rtrim "__rtrim"
return ${TRUE}
}
#F01.20.01
#Function : _str2lower, lower all characters
#Syntaxe : _str2lower
#Return : 1=OK
#Notes : export the text variable in __str2lower
# : Just because this fucking KSH doesn't yet support the Case modification like Bash
_str2lower() {
myDebug ${__MYDEBUG} "_str2lower(${@})"
_alphaHigh="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
_alphaLow="abcdefghijklmnopqrstuvwxyz"
_incr=0
__str2lower="${@}"
while [ $_incr -ne ${#_alphaHigh} ]; do
_upper=${_alphaHigh:$_incr:1}
_lower=${_alphaLow:$_incr:1}
__str2lower="${__str2lower//$_upper/$_lower}"
(( _incr=${_incr}+1 ))
done
export __str2lower
return ${TRUE}
}
#F01.21.01
#Function : _str2upper, upper all characters
#Syntaxe : _str2upper
#Return : 1=OK
#Notes : export the text variable in __str2upper
# : Just because this fucking KSH doesn't yet support the Case modification like Bash
_str2upper() {
myDebug ${__MYDEBUG} "_str2upper(${@})"
_alphaHigh="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
_alphaLow="abcdefghijklmnopqrstuvwxyz"
_incr=0
__str2upper="${@}"
while [ $_incr -ne ${#_alphaHigh} ]; do
_upper=${_alphaHigh:$_incr:1}
_lower=${_alphaLow:$_incr:1}
__str2upper="${__str2upper//$_lower/$_upper}"
(( _incr=${_incr}+1 ))
done
export __str2upper
return ${TRUE}
}
#F01.22.03
#Function : textFill, Create a text filled by the caracter
#Syntaxe : textFill []
#Return : 1=OK
#Notes : export the text variable in __textFill
# : If 3rd value is $TRUE, don't shrink the pattern
textFill() {
myDebug ${__MYDEBUG} "textFill(${@})"
_pattern="${1:- }"
if [ ${#_pattern} -gt 1 -a ${3:-$FALSE} -eq ${FALSE} ]; then _pattern="${_pattern:0:1}"; fi
__textFill=''
_incr=0
while [ ${_incr} -lt ${2:-10} ]; do
__textFill="${__textFill}${_pattern}"
(( _incr=${_incr}+1 ))
done
export __textFill
return ${TRUE}
}
#F01.23.04
#Function : textBox, Create a box around the text
#Syntaxe : textBox <(left|center|right)>
#Return : 1=OK
#Notes : export the text variable in __textBox
# : All catacters \t, \n, \r and space are removed.
# : When used with Bash the function _textBox4Bash is called.
textBox() {
myDebug ${__MYDEBUG} "textBox(${@})"
# if only KSH support <(cmd) for the while; do ; done < like Bash
if [ ${__bash} -eq ${TRUE} ]; then
if [ "x${__BASH_EXTENSION}" = 'xloaded' ]; then
case "${#}" in
1) _textBox4Bash "${1}" ;;
2) _textBox4Bash "${1}" "${2}" ;;
3) _textBox4Bash "${1}" "${2}" "${3}" ;;
esac
return ${TRUE}
else
myError "textBox: Bash Extention is not loaded ! Can't call _textBox4Bash. Aborting..."
export __textBox="${1}"
return ${FALSE}
fi
fi
_max=0
# if only KSH supoprt Case modificatino like Bash
# if [ ! -z "${3}"]; then _align="${3}"; _align="${_align,,}"; else _align="left"; fi
if [ ${#} -gt 2 ]; then
_str2lower "${3}"
_align="${__str2lower}"
else
_align="left"
fi
eval $(
p2s "${1}" | while read _string; do
if [ ${#_string} -gt ${_max} ]; then export _max=${#_string}; fi
p2s "_max=${_max};"
done
)
#let _maxRow=${_max}+4
(( _maxRow=${_max}+4 ))
_padding="${2}"
__textBox=''
p2sp "${1}" | while read _string; do
_subString=""
case "${_align}" in
center)
#let "_padLeft=(${_max}-${#_string})/2"
(( _padLeft=(${_max}-${#_string})/2 ))
#let _padRight=${_max}-${#_string}-${_padLeft}
(( _padRight=${_max}-${#_string}-${_padLeft} ))
textFill ' ' ${_padLeft}
_subString="${_padding} ${__textFill}${_string}"
textFill ' ' ${_padRight}
_subString="${_subString}${__textFill} ${_padding}"
;;
left|right|*)
#let _pad=${_max}-${#_string}
(( _pad=${_max}-${#_string} ))
textFill ' ' ${_pad}
if [ "${_align}" = "right" ]; then
_subString="${_padding} ${__textFill}${_string} ${_padding}"
else
_subString="${_padding} ${_string}${__textFill} ${_padding}"
fi
;;
esac
__textBox="${__textBox}${_subString}\n"
done
textFill "${2}" ${_maxRow}
__textBox="${__textFill}\n${__textBox}${__textFill}"
export __textBox
return ${TRUE}
}
#F01.24.09
#Function : parseHeadersForHelp, Print headers of function for a given file
#Syntaxe : parseHeadersForHelp [fn] [s|search ]
#Return : 1=OK, O=FAIL
#Notes : fn argument just return the function name
# : s or search argument just return the function when name is matching (case sensitive)
# : is or isearch argument just return the function when name is matching (case insensitive)
# : Headers must begin with #F??. (where ?? are two characters),
# : and each line after must begin with a #.
parseHeadersForHelp() {
myDebug ${__MYDEBUG} "parseHeadersForHelp(${@})"
_onlyFunctionName=0; _searchFunction=0; _searchFunctionName=''
_fileName="${1}"
shift
fileCheck "${_fileName}"
if [ ${?} -ne ${TRUE} ]; then
oops "Can't open/read File '${_fileName}' (error: ${__lastError})"
fi
while [ $# -ne 0 ]; do
_str2lower "${1}"
if [ ${_searchFunction} -ge 1 -a ${_searchFunction} -le 2 -a -z "${_searchFunctionName}" ]; then
_searchFunctionName="${1}"
elif [ "x${__str2lower}x" = 'xfnx' ]; then
_onlyFunctionName=1
elif [ "x${__str2lower}x" = 'xsx' -o "x${__str2lower}x" = 'xsearchx' ]; then
_searchFunction=1
elif [ "x${__str2lower}x" = 'xisx' -o "x${__str2lower}x" = 'xisearchx' ]; then
_searchFunction=2
else
myError "parseHeadersForHelp: Argument '${1}' is unknown !"
fi
shift
done
if [ -z "${_searchFunctionName}" ]; then
_searchFunction=0
fi
_beginBlock=0
_forceEndBlock=0
while read a; do
if [ "x${a:0:2}x" = 'x#Fx' -a "x${a:4:1}x" = 'x.x' ]; then
_beginBlock=1
_headers="\033[01;31m${a}\033[0m\n"
elif [ "x${a:0:1}x" = 'x#x' -a ${_beginBlock} -eq 1 ]; then
#_str2lower "${a}"
#if [ ${_searchFunction} -ge 1 -a ${_searchFunction} -le 2 -a "x${__str2lower%% : *}x" = 'x#functionx' ]; then
if [ ${_searchFunction} -ge 1 -a ${_searchFunction} -le 2 -a "x${a%% : *}x" = 'x#Functionx' ]; then
if [ ${_searchFunction} -eq 2 ]; then
b="${a}"
_str2lower "${a}"
export a="${__str2lower}"
_str2lower "${_searchFunctionName}"
export _searchFunctionName="${__str2lower}"
fi
if [ "x${a//*$_searchFunctionName*/$_searchFunctionName}x" != "x${_searchFunctionName}x" ]; then
_beginBlock=0
fi
if [ ${_searchFunction} -eq 2 ]; then
a="${b}"
unset b
fi
fi
if [ ${_beginBlock} -eq 1 ]; then
#_str2lower "${a}"
if [ ${_onlyFunctionName} -eq 0 ]; then
_headers="${_headers}${a}\n"
#elif [ "x${__str2lower%% : *}x" = 'x#functionx' ]; then
elif [ "x${a%% : *}x" = 'x#Functionx' ]; then
_headers="${_headers}${a}\n"
fi
fi
elif [ ${_beginBlock} -eq 1 -o ${_forceEndBlock} -eq 1 ]; then
_beginBlock=0
_forceEndBlock=0
p2sp "${_headers}"
fi
done < "${_fileName}"
}
#F01.25.05
#Function : statusBar, Print (or return) datas to make a status bar
#Syntaxe : statusBar []
#Return : 1=OK
#Notes : export the text variable in __statusBar
# : Instead of having multi variable exported only the one as second arg is set
# : If third argument is set nothing is printed
# : __statusBarPercent2Print (Global) is could be set before call
export __statusBarPercent2Print=5
statusBar() {
myDebug ${__MYDEBUG} "statusBar(${@})"
_globalVariableName="${2}"
__statusBar=''
if [ ${1} -eq 0 ]; then
__statusBar='0'
_statusBarPrevious=0
_statusBarNextLevel=${__statusBarPercent2Print}
_statusBarInitComplete=0
elif [ ${1} -gt 100 ]; then
set -- 100 "${_globalVariableName}"
else
eval _tmp=\$${_globalVariableName}
_statusBarPrevious=${_tmp//::*}
__statusBarPercent2Print=${_tmp//*::}
_tmp=${_tmp#*::}; _statusBarNextLevel=${_tmp//::*}
#myDebug 6 "\n${_statusBarPrevious}-${_statusBarNextLevel}-${__statusBarPercent2Print}"
fi
while [ ${1} -gt ${_statusBarPrevious} ]; do
if [ ${1} -lt ${_statusBarNextLevel:=$__statusBarPercent2Print} ]; then
#let __=${1}-${_statusBarPrevious}
(( __=${1}-${_statusBarPrevious} ))
#let _statusBarPrevious=${_statusBarPrevious}+${__}
(( _statusBarPrevious=${_statusBarPrevious}+${__} ))
textFill '.' ${__}
__statusBar="${__statusBar}${__textFill}"
elif [ ${1} -eq ${_statusBarNextLevel} ]; then
textFill '.' $((${1}-${_statusBarPrevious}-1))
__statusBar="${__statusBar}${__textFill}${_statusBarNextLevel}"
_statusBarPrevious=${_statusBarNextLevel}
(( _statusBarNextLevel=${_statusBarNextLevel}+${__statusBarPercent2Print} ))
else
textFill '.' $((${_statusBarNextLevel}-${_statusBarPrevious}-1))
__statusBar="${__statusBar}${__textFill}${_statusBarNextLevel}"
_statusBarPrevious=${_statusBarNextLevel}
(( _statusBarNextLevel=${_statusBarNextLevel}+${__statusBarPercent2Print} ))
fi
done
if [ ${_statusBarInitComplete:=0} -eq 0 -o ${1} -gt 1 ]; then
export _statusBarInitComplete=1
export __statusBar
if [ -z "${3}" ]; then
printf -- "${__statusBar}"
fi
if [ ${1} -lt 100 ]; then
export eval "${_globalVariableName}=${_statusBarPrevious}::${_statusBarNextLevel}::${__statusBarPercent2Print}"
fi
else
export __statusBar=''
fi
}
#F01.26.01
#Function : randomString, Return a string containing random data
#Syntaxe : randomString ""
#Return : 1=OK, 0=format unknown
#Notes : export the text variable in $varName
# : Format : 1st digit : value betwen 0-9
# : Format : 2sd digit : value betwen a-z
# : Format : 3rd digit : value betwen A-Z
# : It suppose /dev/urandom exists and tr & head available
randomString() {
myDebug ${__MYDEBUG} "randomString(${@})"
_s=''
if [ "x${1}" = 'x000' -o ${#1} -ne 3 ]; then
myError "randomString: Format error : '${1}' !"
return ${FALSE}
fi
if [ ${2} -lt 1 ]; then
myError "randomString: Length is too short !"
return ${FALSE}
fi
if [ -z "${3}" ]; then
myError "randomString: Variable name is empty !"
return ${FALSE}
fi
if [ ${1:0:1} -eq 1 ]; then
_s="${_s}0-9"
fi
if [ ${1:1:1} -eq 1 ]; then
_s="${_s}a-z"
fi
if [ ${1:2:1} -eq 1 ]; then
_s="${_s}A-Z"
fi
eval "export ${3}=$(
#Return : nothing
#Notes :
_e2s() {
[[ ${__bash} -eq ${TRUE} ]] && builtin echo -n "${@}" || command echo -n "${@}"
}
#F01.28.02
#Function : e2s, echo to screen string passed in argument (with an end of line)
#Syntaxe : e2s
#Return : nothing
#Notes : Usefull when you have to print something with percent symbol %
e2s() {
[[ ${__bash} -eq ${TRUE} ]] && builtin echo "${@}" || command echo "${@}"
}
#F01.29.01
#Function : isNum, return True if the value is numeric
#Syntaxe : isNum
#Return : nothing
#Notes : The second argument force to be less permissive
isNum() {
myDebug ${__MYDEBUG} "isNum(${@})"
if [ -z "${1:-}" ]; then return ${FALSE}; fi
if [ "x${2:-$FALSE}" = "x${FALSE}" ]; then
if [ "${1//[^-+.,0-9]/}" = "${1}" ]; then return ${TRUE}; fi
else
if [ "${1//[^0-9]/}" = "${1}" ]; then return ${TRUE}; fi
fi
return ${FALSE}
}
#F01.30.03
#Function : missingCommands, Verify if needed command are existing, else quit
#Syntaxe : missingCommands
#Return : nothing
#Notes : this function check either programme (binaries) or function
# : this function has been imported from megaGetDLoad.sh
missingCommands () {
myDebug ${__MYDEBUG} "missingCommands(${@})"
if [ -z "${1:-}" ]; then return ${FALSE}; fi
for neededCommand in ${1:-}; do
if ! isFunction "${neededCommand}" 1; then
missingCommands="${missingCommands:=} ${neededCommand}"
fi
done
if [ ! -z "${missingCommands:=}" ]; then
err2sp "List of command(s) not in PATH: (${missingCommands} )\nAborting..."
exit 255
fi
}
#F01.31.01
#Function : err2s(p), Print to screen (percent) string passed in argument (with an end of line) on stderr
#Syntaxe : err2s(p)
#Return : nothing
#Notes :
err2s () {
myDebug ${__MYDEBUG} "err2s(${@})"
p2s "${@}" >&2
}
err2sp () {
myDebug ${__MYDEBUG} "err2sp(${@})"
p2sp "${@}" >&2
}
#F01.32.01
#Function : getPidParent, Find the Parent of the given PID
#Syntaxe : getPidParent
#Return : nothing
#Notes :
getPidParent () {
myDebug ${__MYDEBUG} "getPidParent(${@})"
eval export "${2}"='$(ps --no-header -o ppid -p ${1})'
}
#F01.33.01
#Function : getPidParents, Find the Parents of the given PID
#Syntaxe : getPidParent
#Return : nothing
#Notes : Force __includeInit to TRUE to include Init Father
getPidParents () {
myDebug ${__MYDEBUG} "getPidParents(${@})"
_myLocalParents=${1}
while [ ! -z "${_myLocalParents}" -a ${_myLocalParents} -ne 1 ]; do
getPidParent ${_myLocalParents} '_myLocalParents'
if [ ${_myLocalParents} -ne 1 -o ${__includeInit:=$FALSE} -eq ${TRUE} ]; then
eval export "${2}"="'$(eval echo "\$${2}") ${_myLocalParents}'"
fi
done
}
#F01.34.01
#Function : getPidSons, Find the Sons of the given PID
#Syntaxe : getPidParent
#Return : nothing
#Notes :
getPidSons () {
myDebug ${__MYDEBUG} "getPidSons(${@})"
_myLocalSons="$(ps --no-header -o pid --ppid ${1})"
export _mySonsParsed="${_mySonsParsed:= }"
for _pid in ${_myLocalSons:= }; do
if [ "x${_mySonsParsed//* $_pid */$_pid}" != "x${_pid}" ]; then
export _mySonsParsed="${_mySonsParsed:=}${_pid} "
getPidSons ${_pid} '_myLocalSons'
fi
done
eval export "${2}"='${_mySonsParsed}'
}
#F01.35.02
#Function : getPidFamily, Find the All the Familly of a PID (include this PID)
#Syntaxe : getPidFamily
#Return : nothing
#Notes :
getPidFamily () {
myDebug ${__MYDEBUG} "getPidFamily(${@})"
getPidParents ${1} '_getPidFamily'
_trim '_getPidFamily'
if [ -z "${_getPidFamily}" ]; then
_ancestor=${1}
else
_ancestor=${_getPidFamily##* }
fi
getPidSons ${_ancestor} "${2}"
eval export "${2}"='"${_ancestor} $(eval echo "\$${2}")"'
}
#F01.36.01
#Function : cryptContent, crypt the stream with openssl or rot13like
#Syntaxe : cryptContent
#Return : nothing
#Notes : You SHOULD change the change _saltKey variable before calling this function.
cryptContent () {
myDebug ${__MYDEBUG} "cryptContent(${@})"
if isFunction 'openssl' 1; then
cat | openssl aes-256-cbc -a -salt -k "${_saltKey:=LeSaucissonCestBonPourLesBoutons}"
else
cat | tr 'a-zA-Z0-9' 'N-ZA-Mn-za-m5-90-4'
fi
}
#F01.36.01
#Function : decryptContent, decrypt the stream with openssl or rot13like
#Syntaxe : decryptContent []
#Return : nothing
#Notes : You SHOULD change the change _saltKey variable before calling this function.
# : And of course, use the same as when you called the cryptContent function.
decryptContent () {
myDebug ${__MYDEBUG} "decryptContent(${@})"
#if isFunction 'openssl' 1 -a "${1:-}" != 'rot' ; then
if isFunction 'openssl' 1; then
cat | openssl aes-256-cbc -a -d -k "${_saltKey:=LeSaucissonCestBonPourLesBoutons}"
elif [ "${1:-}" = 'openssl' ]; then
cat | openssl aes-256-cbc -a -d -k "${_saltKey:=LeSaucissonCestBonPourLesBoutons}"
else
cat | tr 'N-ZA-Mn-za-m5-90-4' 'a-zA-Z0-9'
fi
}
# ############################################################################ #
# Library related Functions
# ############################################################################ #
#F01.99.05
#Function : F01Version, Return/Print version information
#Syntaxe : F01Version [<1>]
#Return : 1=OK
#Notes : __F01Version contains the result
F01Version() {
myDebug 1 "F01Version(${1})"
_rev='$Revision$'
export __F01Version="common.lib v${F01VERSION} / p${F01PROTOCOL} [${_rev}]"
if [ "x${BASH_VERSION}" != "x" -a "x${KSH_VERSION}" = "x" ]; then
__F01Version="${__F01Version} (with Bash extension : ${__BASH_EXTENSION_LOCATION})"
fi
if [ -z "${1}" ]; then p2s "${__F01Version}"; fi
return ${TRUE}
}
# ############################################################################ #
# Variables Initialisation
# ############################################################################ #
# Debug Variables
F01DEBUG=${F01DEBUG:=0} # Forced to be Level 0, if not defined
__MYDEBUG=${__MYDEBUG:=9} # Forced to be Level 9, if not defined
# Boolean definition
export FALSE=1 # An Integer
export TRUE=0 # An Integer
export NULL='00' # ! A String !
# In some earlier version of Date, we could use the %s
# Verify presence of Perl
if [ "$(date "+%s" 2>/dev/null)" != "%s" ]; then __utsCmd="date +%s"
elif [ -z "$(command -v perl 2>/dev/null)" ]; then __utsCmd="perl -e 'print time();'"
else __utsCmd=''; fi; export __utsCmd
# Verify presence of stat
if [ -z "$(command -v stat 2>/dev/null)" ]; then export __cmdSTAT=0; else export __cmdSTAT=1; fi
# Check and Set : Bash or Ksh or Zsh
export __bash=${FALSE}; export __ksh=${FALSE}; export __zsh=${FALSE};
if [ "x${BASH_VERSION}" != "x" ]; then
export __bash=${TRUE}
elif [ "x${KSH_VERSION}" != "x" ]; then
export __ksh=${TRUE}
elif [ "x${ZSH_VERSION}" != "x" ]; then
export __zsh=${TRUE};
fi
# Initialize Default Log Variables
export __logDir="${__logDir:=/tmp}"
export __logFile="${__logFile:=logFile.log}"
export __logFileV="${__logFileV:=logFileV.log}"
export __logFileSize="${__logFileSize:=21600}" # 60 hours with 1 line/sec
export __logFileVSize="${__logFileVSize:=43200}" # 120 hours with 1 line/sec
#if [ -z "${__logDir}" ]; then export __logDir='/tmp'; fi
#if [ -z "${__logFile}" ]; then export __logFile='logFile.log'; fi
#if [ -z "${__logFileV}" ]; then export __logFileV='logFileV.log'; fi
#if [ -z "${__logFileSize}" ]; then export __logFileSize=21600; fi # 60 hours with 1 line/sec
#if [ -z "${__logFileVSize}" ]; then export __logFileVSize=43200; fi # 120 hours with 1 line/sec
# As Prerequisites for Bash the subLibrary _common4bash.lib is needed
# But it will not stop your program if not loaded
if [ ${__bash} -eq ${TRUE} ]; then
if [ ${BASH_VERSINFO[0]} -lt 4 -a ${BASH_VERSINFO[1]} -lt 3 -a ${BASH_VERSINFO[2]} -lt 26 ]; then
# Due to some limitations with Bash 3.2.25 and inferior, I don't load it
__BASH_EXTENSION_LOCATION='Not Supported ! Bash too old.'
else
if [ -f "${BASH_SOURCE%/*}/_common4bash.lib" ]; then
. "$(cd ${BASH_SOURCE%/*}; pwd)/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="$(cd ${BASH_SOURCE%/*}; pwd)/_common4bash.lib"
elif [ -f "${0%/*}/_common4bash.lib" ]; then
. "${0%/*}/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/_common4bash.lib"
elif [ -f "${0%/*}/../_common4bash.lib" ]; then
. "${0%/*}/../_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/../_common4bash.lib"
elif [ -f "${0%/*}/include/_common4bash.lib" ]; then
. "${0%/*}/include/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/include/_common4bash.lib"
elif [ -f "${0%/*}/lib/_common4bash.lib" ]; then
. "${0%/*}/lib/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/lib/_common4bash.lib"
elif [ -f "${0%/*}/prereq/_common4bash.lib" ]; then
. "${0%/*}/prereq/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/prereq/_common4bash.lib"
elif [ -f "${0%/*}/prereqs/_common4bash.lib" ]; then
. "${0%/*}/prereqs/_common4bash.lib"
export __BASH_EXTENSION_LOCATION="${0%/*}/prereqs/_common4bash.lib"
else
export __BASH_EXTENSION_LOCATION='Not Found !'
fi
fi
fi
# Have a look for Missing Commands used internally
if [ ${__zsh} -ne ${TRUE} ]; then
if [ "x$(uname -s)" != "xAIX" ]; then
missingCommands "stat"
fi
missingCommands "printf echo head sed chmod rm tr wc"
fi
# +---------------------------------------------------------------------------+ #
# | Last subversion informations :
# | $URL$
# | $Revision$ : $Date$
# | $Author$
# +---------------------------------------------------------------------------+ #