6130 lines
165 KiB
Bash
Executable File
6130 lines
165 KiB
Bash
Executable File
#!/bin/bash
|
||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||
#source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
||
#urequire DEFAULTS crontab
|
||
# Pour pouvoir être copié le cas échéant sur un hôte distant, la librairie ulib
|
||
# est inclue avec uinc à partir de lib/ulib. En mode développement, il faut
|
||
# replier les inclusions avec uinc -f et décommenter les lignes ci-dessus
|
||
|
||
function display_help() {
|
||
uecho "$scriptname: Ajouter/Supprimer une ligne dans crontab
|
||
|
||
USAGE
|
||
$scriptname [options] ctline
|
||
|
||
OPTIONS
|
||
-a Ajouter la ligne dans le fichier crontab (par défaut)
|
||
-r Enlever la ligne dans le fichier crontab
|
||
-u user
|
||
Spécifier l'utilisateur pour lequel on modifie crontab. Par défaut,
|
||
modifier le crontab de root
|
||
-H host:hosts...
|
||
Modifier le crontab sur les hôtes distants spécifiés. Avec l'hôte '.' ou
|
||
'localhost', la modification est faite sur l'hôte local
|
||
Si l'action est -a, un script 'undo-ucrontab.sh' est créé dans le
|
||
répertoire courant, qui annule la planification. Il est possible de
|
||
lancer ce script le lendemain pour enlever les planifications
|
||
installées.
|
||
ctline
|
||
Ligne de crontab de la forme 'minutes hours days months dows command'
|
||
Si la ligne est de la forme halt[@hh:mm], la commande 'shutdown -h now'
|
||
est planifiée pour le LENDEMAIN à hh:mm. si hh:mm n'est pas spécifié,
|
||
l'arrêt est planifié pour 7:00
|
||
-t hh:mm
|
||
Ignorer la partie 'minutes hours days months dows' de ctline, et la
|
||
remplacer par une planification à hh:mm le LENDEMAIN.
|
||
--dom dayOfMonth
|
||
--month month
|
||
Spécifier respectivement le jour du mois et le mois (1-12) auquel faire
|
||
la planification. Par défaut, les planifications sont effectuées pour le
|
||
LENDEMAIN. Il est conseillé de spécifier les deux arguments si le jour
|
||
doit être fixé.
|
||
-s cmdfile
|
||
Spécifier un fichier, dont le contenu est utilisé pour générer le script
|
||
qui est planifié. Le fichier doit contenir l'ensemble des commandes à
|
||
exécuter. Le script est modifié pour s'autodétruire à la fin de son
|
||
exécution. Si ce comportement n'est pas souhaité, il faut rajouter la
|
||
commande 'exit 0' à la fin.
|
||
-S cmd
|
||
Comme -s, mais spécifier le contenu du fichier directement sur la ligne
|
||
de commande.
|
||
-f hostsfile
|
||
Spécifier un fichier qui contient la liste des hôtes sur lesquels faire
|
||
les planifications.
|
||
Les options -s, -S, -H, -d, -n sont ignorées. L'option --add est valide
|
||
jusqu'au premier @group du fichier. Voici le format de ce fichier:
|
||
|
||
Un groupe d'hôte débute par une ligne de la forme '@group:adelay:gdelay'
|
||
- adelay est le nombre de minutes à laisser passer entre les hôtes du
|
||
groupe (par défaut 1)
|
||
- gdelay est le nombre de minutes à laisser passer après le traitement
|
||
du groupe (par défaut 15)
|
||
Les autres lignes sont des hôtes sur lequels planifier l'opération, de
|
||
la forme 'host:cmd'
|
||
- host est un nom d'hôte pleinement qualifié, sur lequel il est possible
|
||
de se connecter par clé.
|
||
- cmd est une description de la commande à lancer pour effectuer
|
||
l'opération planifiée. Utiliser la syntaxe '<script' pour prendre le
|
||
contenu du fichier de script spécifié. Le script est copié dans un
|
||
fichier temporaire sur l'hôte, et se supprime après son
|
||
lancement. Sinon, la commande spécifiée est utilisée telle quelle. Si
|
||
cmd n'est pas spécifié, prendre la commande par défaut donnée par
|
||
ctline
|
||
Les lignes vides et commençant par '#' sont ignorées
|
||
La commande '@include:file' permet d'inclure un autre fichier
|
||
|
||
-d Activer l'incrémentation automatique des heures de planification entre
|
||
chaque hôte. Ceci permet par exemple de planifier l'arrêt d'un certain
|
||
nombre de machines dans un ordre précis, en horaire décalé.
|
||
Cette option est activée par défaut si ctline==halt[@time]
|
||
-n Désactiver l'incrémentation automatique des heures de planification.
|
||
--add ADELAY
|
||
Spécifier le nombre de minutes entre chaque hôte pour l'incrémentation
|
||
automatique des heures de planification. Par défaut, il y a 1 minute
|
||
entre chaque hôte.
|
||
--us undo-script
|
||
Spécifier le nom du script qui annule la planification. Utiliser \"\"
|
||
pour désactiver cette fonctionnalité.
|
||
--fake
|
||
Afficher simplement les modifications qui doivent être effectuées."
|
||
}
|
||
|
||
DEFAULT_ADELAY=1
|
||
DEFAULT_GDELAY=15
|
||
|
||
##@inc[base
|
||
## Fonctions de base
|
||
##@*inc[base.ulib
|
||
## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
|
||
## cas où cette librairie n'est pas chargée
|
||
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
|
||
ULIBPROVIDED=()
|
||
function uprovided() {
|
||
local module
|
||
for module in "${ULIBPROVIDED[@]}"; do
|
||
[ "$module" == "$1" ] && return 0
|
||
done
|
||
return 1
|
||
}
|
||
function uprovide() {
|
||
uprovided "$1" && return 1
|
||
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
|
||
}
|
||
function urequire() {
|
||
local module r=0
|
||
for module in "$@"; do
|
||
uprovided "$module" && continue
|
||
echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
|
||
r=1
|
||
done
|
||
return $r
|
||
}
|
||
uprovide base.ulib
|
||
fi
|
||
##@*inc]base.ulib
|
||
##@inc[base.init
|
||
## Fonctions de base: initialisation de l'environnement
|
||
|
||
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
|
||
:
|
||
elif [ "$0" == "-bash" ]; then
|
||
scriptname=
|
||
scriptdir=
|
||
script=
|
||
elif [ ! -f "$0" -a -f "${0#-}" ]; then
|
||
scriptname="$(basename -- "${0#-}")"
|
||
scriptdir="$(dirname -- "${0#-}")"
|
||
scriptdir="$(cd "$scriptdir"; pwd)"
|
||
script="$scriptdir/$scriptname"
|
||
else
|
||
scriptname="$(basename -- "$0")"
|
||
scriptdir="$(dirname -- "$0")"
|
||
scriptdir="$(cd "$scriptdir"; pwd)"
|
||
script="$scriptdir/$scriptname"
|
||
fi
|
||
: "${ULIBDIR:=$scriptdir}"
|
||
|
||
[ -z "$TMPDIR" -a -d "$HOME/tmp" ] && TMPDIR="$HOME/tmp"
|
||
export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
|
||
|
||
[ -z "$USER" -a -n "$LOGNAME" ] && export USER="$LOGNAME"
|
||
|
||
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
|
||
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
|
||
true
|
||
##@inc]base.init
|
||
##@inc[base.core
|
||
## Fonctions de base: fondement
|
||
uprovide base.core
|
||
|
||
function echo_() {
|
||
echo -n "$*"
|
||
}
|
||
function recho() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo "$first$@"
|
||
else
|
||
echo "$@"
|
||
fi
|
||
}
|
||
function recho_() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo -n "$first$@"
|
||
else
|
||
echo -n "$@"
|
||
fi
|
||
}
|
||
function _qval() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\"/\\\"}"
|
||
s="${s//\$/\\\$}"
|
||
s="${s//\`/\\\`}"
|
||
recho_ "$s"
|
||
}
|
||
function should_quote() {
|
||
[ -z "$1" ] && return 0
|
||
local s="${*//[a-zA-Z0-9]/}"
|
||
s="${s//,/}"
|
||
s="${s//./}"
|
||
s="${s//+/}"
|
||
s="${s//\//}"
|
||
s="${s//-/}"
|
||
s="${s//_/}"
|
||
s="${s//=/}"
|
||
[ -n "$s" ]
|
||
}
|
||
function qval() {
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
}
|
||
function qvalm() {
|
||
if should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvalr() {
|
||
if [ -z "$*" ]; then
|
||
:
|
||
elif should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvals() {
|
||
local arg first=1
|
||
for arg in "$@"; do
|
||
[ -z "$first" ] && echo -n " "
|
||
if should_quote "$arg"; then
|
||
echo -n \"
|
||
_qval "$arg"
|
||
echo -n \"
|
||
else
|
||
recho_ "$arg"
|
||
fi
|
||
first=
|
||
done
|
||
[ -z "$first" ] && echo
|
||
}
|
||
function qlines() {
|
||
sed "s/'/'\\\\''/g; s/.*/'&'/g"
|
||
}
|
||
function setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function _setv() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function echo_setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
echo "$__s_var=$(qvalr "$*")"
|
||
}
|
||
function setx() {
|
||
if [ "$1" == -a ]; then
|
||
shift
|
||
local __s_array="$1"; shift
|
||
if [[ "$__s_array" == *=* ]]; then
|
||
set -- "${__s_array#*=}" "$@"
|
||
__s_array="${__s_array%%=*}"
|
||
fi
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
else
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var="'"$("$@")"'
|
||
fi
|
||
}
|
||
function _setvx() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var="'"$("$@")"'
|
||
}
|
||
function _setax() {
|
||
local __s_array="$1"; shift
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
}
|
||
function evalx() {
|
||
local __e_val __e_arg __e_r=0
|
||
local -a __e_cmd
|
||
|
||
local __e_first=1
|
||
while [ $# -gt 0 ]; do
|
||
__e_cmd=()
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
[ "$__e_arg" == // ] && break
|
||
if [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
continue
|
||
fi
|
||
fi
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
done
|
||
|
||
if [ -n "$__e_first" ]; then
|
||
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
|
||
else
|
||
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
|
||
fi
|
||
__e_first=
|
||
done
|
||
[ -n "$__e_val" ] && echo "$__e_val"
|
||
return $__e_r
|
||
}
|
||
function setxx() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalx "$@"
|
||
}
|
||
function evalp() {
|
||
local __e_arg __e_cmd
|
||
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
if [ "$__e_arg" == // ]; then
|
||
__e_cmd="$__e_cmd |"
|
||
continue
|
||
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
fi
|
||
fi
|
||
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
|
||
done
|
||
eval "$__e_cmd"
|
||
}
|
||
function setxp() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalp "$@"
|
||
}
|
||
function testx() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalx "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2x() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrx() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
function testp() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalp "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2p() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrp() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
|
||
function err2out() {
|
||
"$@" 2>&1
|
||
}
|
||
##@inc]base.core
|
||
##@inc[base.string
|
||
## Fonctions de base: gestion des valeurs scalaires
|
||
uprovide base.string
|
||
urequire base.core
|
||
|
||
function straddp() {
|
||
local p="$1"; shift
|
||
echo "$p$*"
|
||
}
|
||
function strdelp() {
|
||
local p="$1"; shift
|
||
local str="$*"
|
||
echo "${str#$p}"
|
||
}
|
||
function strdelp2() {
|
||
local p="$1"; shift
|
||
local str="$*"
|
||
echo "${str##$p}"
|
||
}
|
||
function stradds() {
|
||
local s="$1"; shift
|
||
echo "$*$s"
|
||
}
|
||
function strdels() {
|
||
local s="$1"; shift
|
||
local str="$*"
|
||
echo "${str%$s}"
|
||
}
|
||
function strdels2() {
|
||
local s="$1"; shift
|
||
local str="$*"
|
||
echo "${str%%$s}"
|
||
}
|
||
function strlower() {
|
||
local str="$*"
|
||
echo "${str,,}"
|
||
}
|
||
function strlower1() {
|
||
local str="$*"
|
||
echo "${str,}"
|
||
}
|
||
function strlowers() {
|
||
local str="$*"
|
||
echo "${*,}"
|
||
}
|
||
function strupper() {
|
||
local str="$*"
|
||
echo "${str^^}"
|
||
}
|
||
function strupper1() {
|
||
local str="$*"
|
||
echo "${str^}"
|
||
}
|
||
function struppers() {
|
||
echo "${*^}"
|
||
}
|
||
function strmid() {
|
||
local range="$1"; shift
|
||
local str="$*"
|
||
if [[ "$range" == *:-* ]]; then
|
||
local max=${#str}
|
||
[ $max -eq 0 ] && return
|
||
local start="${range%%:*}"
|
||
[ -n "$start" ] || start=0
|
||
while [ "$start" -lt 0 ]; do
|
||
start=$(($max$start))
|
||
done
|
||
max=$(($max-$start))
|
||
local length="${range#*:}"
|
||
while [ "$length" -lt 0 ]; do
|
||
length=$(($max$length))
|
||
done
|
||
range="$start:$length"
|
||
fi
|
||
eval 'echo "${str:'" $range"'}"'
|
||
}
|
||
function strrepl() {
|
||
local pattern="$1"; shift
|
||
local repl="$1"; shift
|
||
local str="$*"
|
||
local cmd='echo "${str/'
|
||
if [ "${pattern#/}" != "$pattern" ]; then
|
||
pattern="${pattern#/}"
|
||
cmd="$cmd/"
|
||
elif [ "${pattern#\#}" != "$pattern" ]; then
|
||
pattern="${pattern#\#}"
|
||
cmd="$cmd#"
|
||
elif [ "${pattern#%}" != "$pattern" ]; then
|
||
pattern="${pattern#%}"
|
||
cmd="$cmd%"
|
||
fi
|
||
cmd="$cmd"'$pattern/$repl}"'
|
||
eval "$cmd"
|
||
}
|
||
|
||
function first_char() {
|
||
local str="$*"
|
||
echo "${str:0:1}"
|
||
}
|
||
function last_char() {
|
||
local str="$*"
|
||
echo "${str: -1:1}"
|
||
}
|
||
function first_chars() {
|
||
local str="$*"
|
||
recho "${str:0:$((${#1}-1))}"
|
||
}
|
||
function last_chars() {
|
||
local str="$*"
|
||
recho "${str:1}"
|
||
}
|
||
function first_char_is() {
|
||
[ "${1:0:1}" == "$2" ]
|
||
}
|
||
function last_char_is() {
|
||
[ "${1:$((-1)):1}" == "$2" ]
|
||
}
|
||
function beginswith() {
|
||
local str="$1" pattern="$2"
|
||
eval '[ "${str#$pattern}" != "$str" ]'
|
||
}
|
||
function endswith() {
|
||
local str="$1" pattern="$2"
|
||
eval '[ "${str%$pattern}" != "$str" ]'
|
||
}
|
||
##@inc]base.string
|
||
##@inc[base.num
|
||
## Fonctions de base: gestion des valeurs numériques
|
||
uprovide base.num
|
||
|
||
function isnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function ispnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function isrnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//./}"
|
||
v="${v//,/}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
##@inc]base.num
|
||
##@inc[base.bool
|
||
## Fonctions de base: valeurs booléennes
|
||
##@inc[base.num
|
||
## Fonctions de base: gestion des valeurs numériques
|
||
uprovide base.num
|
||
|
||
function isnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function ispnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function isrnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//./}"
|
||
v="${v//,/}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
##@inc]base.num
|
||
uprovide base.bool
|
||
urequire base.num
|
||
|
||
function is_yes() {
|
||
case "${1,,}" in
|
||
o|oui|y|yes|v|vrai|t|true|on) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -ne 0 ] && return 0
|
||
return 1
|
||
}
|
||
function is_no() {
|
||
case "${1,,}" in
|
||
n|non|no|f|faux|false|off) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -eq 0 ] && return 0
|
||
return 1
|
||
}
|
||
function yesval() {
|
||
is_yes "$1" && echo 1
|
||
}
|
||
|
||
function setb() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
local __s_r
|
||
if "$@" >/dev/null; then
|
||
eval "$__s_var=1"
|
||
else
|
||
__s_r=$?
|
||
eval "$__s_var="
|
||
return $__s_r
|
||
fi
|
||
}
|
||
function _setb() {
|
||
local __s_var="$1"; shift
|
||
if "$@" >/dev/null; then
|
||
eval "$__s_var=1"
|
||
else
|
||
eval "$__s_var="
|
||
fi
|
||
}
|
||
|
||
function evalb() {
|
||
if evalx "$@" >/dev/null; then
|
||
echo 1
|
||
else
|
||
return $?
|
||
fi
|
||
}
|
||
function setxb() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
setx "$__s_var" evalb "$@"
|
||
}
|
||
##@inc]base.bool
|
||
##@inc[base.array
|
||
## Fonctions de base: gestion des tableaux
|
||
uprovide base.array
|
||
urequire base.core
|
||
##@inc]base.array
|
||
##@inc[base.quote
|
||
## Fonctions de base: protection de valeurs chaine
|
||
uprovide base.quote
|
||
urequire base.core
|
||
|
||
function _qawk() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\"/\\\"}"
|
||
s="${s//
|
||
/\\n}"
|
||
recho_ "$s"
|
||
}
|
||
function qawk() {
|
||
echo -n \"
|
||
_qawk "$@"
|
||
echo \"
|
||
}
|
||
function qseds() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\//\\/}"
|
||
recho "$s"
|
||
}
|
||
function _qform() {
|
||
local s="$*"
|
||
s="${s//\%/%25}"
|
||
s="${s//+/%2B}"
|
||
s="${s//&/%26}"
|
||
s="${s//=/%3D}"
|
||
s="${s// /+}"
|
||
recho_ "$s"
|
||
}
|
||
function qform() {
|
||
local s="$*"
|
||
if [[ "$s" == *=* ]]; then
|
||
_qform "${s%%=*}"
|
||
echo -n =
|
||
_qform "${s#*=}"
|
||
echo
|
||
else
|
||
_qform "$s"
|
||
echo
|
||
fi
|
||
}
|
||
##@inc]base.quote
|
||
##@inc[base.split
|
||
## Fonctions de base: analyse et découpage de valeurs
|
||
uprovide base.split
|
||
urequire base.core
|
||
|
||
function splitfsep() {
|
||
if [[ "$1" == *"$2"* ]]; then
|
||
setv "${3:-first}" "${1%%$2*}"
|
||
setv "${4:-second}" "${1#*$2}"
|
||
else
|
||
setv "${3:-first}" "$1"
|
||
setv "${4:-second}"
|
||
fi
|
||
}
|
||
function splitfsep2() {
|
||
if [[ "$1" == *"$2"* ]]; then
|
||
setv "${3:-first}" "${1%%$2*}"
|
||
setv "${4:-second}" "${1#*$2}"
|
||
else
|
||
setv "${3:-first}"
|
||
setv "${4:-second}" "$1"
|
||
fi
|
||
}
|
||
function splitlsep() {
|
||
if [[ "$1" == *"$2"* ]]; then
|
||
setv "${3:-first}" "${1%$2*}"
|
||
setv "${4:-second}" "${1##*$2}"
|
||
else
|
||
setv "${3:-first}" "$1"
|
||
setv "${4:-second}"
|
||
fi
|
||
}
|
||
function splitlsep2() {
|
||
if [[ "$1" == *"$2"* ]]; then
|
||
setv "${3:-first}" "${1%$2*}"
|
||
setv "${4:-second}" "${1##*$2}"
|
||
else
|
||
setv "${3:-first}"
|
||
setv "${4:-second}" "$1"
|
||
fi
|
||
}
|
||
function splitvar() {
|
||
splitfsep "$1" = "${2:-name}" "${3:-value}"
|
||
}
|
||
function splitname() {
|
||
splitlsep "$1" . "${2:-basename}" "${3:-ext}"
|
||
}
|
||
function splithost() {
|
||
splitfsep "$1" . "${2:-hostname}" "${3:-domain}"
|
||
}
|
||
function splituserhost() {
|
||
splitfsep2 "$1" @ "${2:-user}" "${3:-host}"
|
||
}
|
||
function splitpair() {
|
||
splitfsep "$1" : "${2:-src}" "${3:-dest}"
|
||
}
|
||
function splitproxy() {
|
||
local __sp_tmp __sp_host __sp_port __sp_creds __sp_user __sp_password
|
||
|
||
__sp_tmp="${1#http://}"
|
||
if [[ "$__sp_tmp" == *@* ]]; then
|
||
__sp_creds="${__sp_tmp%%@*}"
|
||
__sp_tmp="${__sp_tmp#${__sp_creds}@}"
|
||
splitpair "$__sp_creds" __sp_user __sp_password
|
||
fi
|
||
__sp_tmp="${__sp_tmp%%/*}"
|
||
splitpair "$__sp_tmp" __sp_host __sp_port
|
||
[ -n "$__sp_port" ] || __sp_port=3128
|
||
|
||
setv "${2:-host}" "$__sp_host"
|
||
setv "${3:-port}" "$__sp_port"
|
||
setv "${4:-user}" "$__sp_user"
|
||
setv "${5:-password}" "$__sp_password"
|
||
}
|
||
function spliturl() {
|
||
local __su_tmp __su_scheme __su_creds __su_user __su_password __su_host __su_port __su_path
|
||
|
||
__su_scheme="${1%%:*}"
|
||
__su_tmp="${1#${__su_scheme}://}"
|
||
if [[ "$__su_tmp" == */* ]]; then
|
||
__su_path="${__su_tmp#*/}"
|
||
__su_tmp="${__su_tmp%%/*}"
|
||
fi
|
||
if [[ "$__su_tmp" == *@* ]]; then
|
||
__su_creds="${__su_tmp%%@*}"
|
||
__su_tmp="${__su_tmp#${__su_creds}@}"
|
||
splitpair "$__su_creds" __su_user __su_password
|
||
fi
|
||
splitpair "$__su_tmp" __su_host __su_port
|
||
if [ -z "$__su_port" ]; then
|
||
[ "$__su_scheme" == "http" ] && __su_port=80
|
||
[ "$__su_scheme" == "https" ] && __su_port=443
|
||
[ "$__su_scheme" == "ftp" ] && __su_port=21
|
||
fi
|
||
|
||
setv "${2:-scheme}" "$__su_scheme"
|
||
setv "${3:-user}" "$__su_user"
|
||
setv "${4:-password}" "$__su_password"
|
||
setv "${5:-host}" "$__su_host"
|
||
setv "${6:-port}" "$__su_port"
|
||
setv "${7:-path}" "$__su_path"
|
||
}
|
||
##@inc]base.split
|
||
##@inc[base.args
|
||
## Analyse des arguments de la ligne de commande
|
||
##@inc[base.core
|
||
## Fonctions de base: fondement
|
||
uprovide base.core
|
||
|
||
function echo_() {
|
||
echo -n "$*"
|
||
}
|
||
function recho() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo "$first$@"
|
||
else
|
||
echo "$@"
|
||
fi
|
||
}
|
||
function recho_() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo -n "$first$@"
|
||
else
|
||
echo -n "$@"
|
||
fi
|
||
}
|
||
function _qval() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\"/\\\"}"
|
||
s="${s//\$/\\\$}"
|
||
s="${s//\`/\\\`}"
|
||
recho_ "$s"
|
||
}
|
||
function should_quote() {
|
||
[ -z "$1" ] && return 0
|
||
local s="${*//[a-zA-Z0-9]/}"
|
||
s="${s//,/}"
|
||
s="${s//./}"
|
||
s="${s//+/}"
|
||
s="${s//\//}"
|
||
s="${s//-/}"
|
||
s="${s//_/}"
|
||
s="${s//=/}"
|
||
[ -n "$s" ]
|
||
}
|
||
function qval() {
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
}
|
||
function qvalm() {
|
||
if should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvalr() {
|
||
if [ -z "$*" ]; then
|
||
:
|
||
elif should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvals() {
|
||
local arg first=1
|
||
for arg in "$@"; do
|
||
[ -z "$first" ] && echo -n " "
|
||
if should_quote "$arg"; then
|
||
echo -n \"
|
||
_qval "$arg"
|
||
echo -n \"
|
||
else
|
||
recho_ "$arg"
|
||
fi
|
||
first=
|
||
done
|
||
[ -z "$first" ] && echo
|
||
}
|
||
function qlines() {
|
||
sed "s/'/'\\\\''/g; s/.*/'&'/g"
|
||
}
|
||
function setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function _setv() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function echo_setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
echo "$__s_var=$(qvalr "$*")"
|
||
}
|
||
function setx() {
|
||
if [ "$1" == -a ]; then
|
||
shift
|
||
local __s_array="$1"; shift
|
||
if [[ "$__s_array" == *=* ]]; then
|
||
set -- "${__s_array#*=}" "$@"
|
||
__s_array="${__s_array%%=*}"
|
||
fi
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
else
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var="'"$("$@")"'
|
||
fi
|
||
}
|
||
function _setvx() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var="'"$("$@")"'
|
||
}
|
||
function _setax() {
|
||
local __s_array="$1"; shift
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
}
|
||
function evalx() {
|
||
local __e_val __e_arg __e_r=0
|
||
local -a __e_cmd
|
||
|
||
local __e_first=1
|
||
while [ $# -gt 0 ]; do
|
||
__e_cmd=()
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
[ "$__e_arg" == // ] && break
|
||
if [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
continue
|
||
fi
|
||
fi
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
done
|
||
|
||
if [ -n "$__e_first" ]; then
|
||
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
|
||
else
|
||
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
|
||
fi
|
||
__e_first=
|
||
done
|
||
[ -n "$__e_val" ] && echo "$__e_val"
|
||
return $__e_r
|
||
}
|
||
function setxx() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalx "$@"
|
||
}
|
||
function evalp() {
|
||
local __e_arg __e_cmd
|
||
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
if [ "$__e_arg" == // ]; then
|
||
__e_cmd="$__e_cmd |"
|
||
continue
|
||
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
fi
|
||
fi
|
||
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
|
||
done
|
||
eval "$__e_cmd"
|
||
}
|
||
function setxp() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalp "$@"
|
||
}
|
||
function testx() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalx "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2x() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrx() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
function testp() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalp "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2p() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrp() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
|
||
function err2out() {
|
||
"$@" 2>&1
|
||
}
|
||
##@inc]base.core
|
||
##@inc[base.string
|
||
## Fonctions de base: gestion des valeurs scalaires
|
||
uprovide base.string
|
||
urequire base.core
|
||
|
||
function straddp() {
|
||
local p="$1"; shift
|
||
echo "$p$*"
|
||
}
|
||
function strdelp() {
|
||
local p="$1"; shift
|
||
local str="$*"
|
||
echo "${str#$p}"
|
||
}
|
||
function strdelp2() {
|
||
local p="$1"; shift
|
||
local str="$*"
|
||
echo "${str##$p}"
|
||
}
|
||
function stradds() {
|
||
local s="$1"; shift
|
||
echo "$*$s"
|
||
}
|
||
function strdels() {
|
||
local s="$1"; shift
|
||
local str="$*"
|
||
echo "${str%$s}"
|
||
}
|
||
function strdels2() {
|
||
local s="$1"; shift
|
||
local str="$*"
|
||
echo "${str%%$s}"
|
||
}
|
||
function strlower() {
|
||
local str="$*"
|
||
echo "${str,,}"
|
||
}
|
||
function strlower1() {
|
||
local str="$*"
|
||
echo "${str,}"
|
||
}
|
||
function strlowers() {
|
||
local str="$*"
|
||
echo "${*,}"
|
||
}
|
||
function strupper() {
|
||
local str="$*"
|
||
echo "${str^^}"
|
||
}
|
||
function strupper1() {
|
||
local str="$*"
|
||
echo "${str^}"
|
||
}
|
||
function struppers() {
|
||
echo "${*^}"
|
||
}
|
||
function strmid() {
|
||
local range="$1"; shift
|
||
local str="$*"
|
||
if [[ "$range" == *:-* ]]; then
|
||
local max=${#str}
|
||
[ $max -eq 0 ] && return
|
||
local start="${range%%:*}"
|
||
[ -n "$start" ] || start=0
|
||
while [ "$start" -lt 0 ]; do
|
||
start=$(($max$start))
|
||
done
|
||
max=$(($max-$start))
|
||
local length="${range#*:}"
|
||
while [ "$length" -lt 0 ]; do
|
||
length=$(($max$length))
|
||
done
|
||
range="$start:$length"
|
||
fi
|
||
eval 'echo "${str:'" $range"'}"'
|
||
}
|
||
function strrepl() {
|
||
local pattern="$1"; shift
|
||
local repl="$1"; shift
|
||
local str="$*"
|
||
local cmd='echo "${str/'
|
||
if [ "${pattern#/}" != "$pattern" ]; then
|
||
pattern="${pattern#/}"
|
||
cmd="$cmd/"
|
||
elif [ "${pattern#\#}" != "$pattern" ]; then
|
||
pattern="${pattern#\#}"
|
||
cmd="$cmd#"
|
||
elif [ "${pattern#%}" != "$pattern" ]; then
|
||
pattern="${pattern#%}"
|
||
cmd="$cmd%"
|
||
fi
|
||
cmd="$cmd"'$pattern/$repl}"'
|
||
eval "$cmd"
|
||
}
|
||
|
||
function first_char() {
|
||
local str="$*"
|
||
echo "${str:0:1}"
|
||
}
|
||
function last_char() {
|
||
local str="$*"
|
||
echo "${str: -1:1}"
|
||
}
|
||
function first_chars() {
|
||
local str="$*"
|
||
recho "${str:0:$((${#1}-1))}"
|
||
}
|
||
function last_chars() {
|
||
local str="$*"
|
||
recho "${str:1}"
|
||
}
|
||
function first_char_is() {
|
||
[ "${1:0:1}" == "$2" ]
|
||
}
|
||
function last_char_is() {
|
||
[ "${1:$((-1)):1}" == "$2" ]
|
||
}
|
||
function beginswith() {
|
||
local str="$1" pattern="$2"
|
||
eval '[ "${str#$pattern}" != "$str" ]'
|
||
}
|
||
function endswith() {
|
||
local str="$1" pattern="$2"
|
||
eval '[ "${str%$pattern}" != "$str" ]'
|
||
}
|
||
##@inc]base.string
|
||
##@inc[base.array
|
||
## Fonctions de base: gestion des tableaux
|
||
uprovide base.array
|
||
urequire base.core
|
||
##@inc]base.array
|
||
uprovide base.args
|
||
urequire base.core base.string base.array #XXX maj de cette liste
|
||
|
||
function __po_parse_optdescs() {
|
||
local -a optdescs_
|
||
local optdesc_ option_ name_ flag_ value_
|
||
local reset_
|
||
local shift_
|
||
local i_ count_
|
||
|
||
let shift_=0
|
||
while [ -n "$1" ]; do
|
||
if [ "$1" == -- ]; then
|
||
shift
|
||
let shift_=$shift_+1
|
||
break
|
||
elif [ "$1" == "%" ]; then
|
||
reset_=1
|
||
shift
|
||
let shift_=$shift_+1
|
||
elif [ "$1" == "-" -o "$1" == "+" ]; then
|
||
if [ "${opts_#+}" != "$opts_" ]; then
|
||
opts_="${opts_#+}"
|
||
elif [ "${opts_#-}" != "$opts_" ]; then
|
||
opts_="${opts_#-}"
|
||
fi
|
||
opts_="$1$opts_"
|
||
shift
|
||
let shift_=$shift_+1
|
||
elif [ "$1" == "@" ]; then
|
||
destargs_="$2"
|
||
shift; shift
|
||
let shift_=$shift_+2
|
||
elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then
|
||
array_split optdescs_ "$1" ","
|
||
if [ "$2" == . ]; then
|
||
local autoname_=
|
||
for optdesc_ in "${optdescs_[@]}"; do
|
||
if [ ${#optdesc_} -gt ${#autoname_} ]; then
|
||
autoname_="$optdesc_"
|
||
fi
|
||
done
|
||
while [ -n "$autoname_" -a "${autoname_#-}" != "$autoname_" ]; do autoname_="${autoname_#-}"; done
|
||
while [ -n "$autoname_" -a "${autoname_%:}" != "$autoname_" ]; do autoname_="${autoname_%:}"; done
|
||
autoname_="${autoname_//-/_}"
|
||
shift; shift
|
||
set -- dummy "$autoname_" "$@"
|
||
fi
|
||
for optdesc_ in "${optdescs_[@]}"; do
|
||
if [[ "$2" == \$* ]]; then
|
||
name_="$2"
|
||
if [[ "$optdesc_" == *:: ]]; then
|
||
option_="${optdesc_%::}"
|
||
flag_='::$'
|
||
elif [[ "$optdesc_" == *: ]]; then
|
||
option_="${optdesc_%:}"
|
||
flag_=':$'
|
||
else
|
||
option_="$optdesc_"
|
||
flag_='$'
|
||
fi
|
||
elif [[ "$optdesc_" == *:: ]]; then
|
||
option_="${optdesc_%::}"
|
||
if [[ "$2" == *=* ]]; then
|
||
name_="${2%%=*}="
|
||
[ -n "$reset_" ] && eval "$name_="
|
||
else
|
||
name_="$2"
|
||
[ -n "$reset_" ] && eval "$name_=()"
|
||
fi
|
||
flag_=::
|
||
elif [[ "$optdesc_" == *: ]]; then
|
||
option_="${optdesc_%:}"
|
||
if [[ "$2" == *=* ]]; then
|
||
name_="${2%%=*}="
|
||
[ -n "$reset_" ] && eval "$name_="
|
||
else
|
||
name_="$2"
|
||
[ -n "$reset_" ] && eval "$name_=()"
|
||
fi
|
||
flag_=:
|
||
else
|
||
option_="$optdesc_"
|
||
name_="$2"
|
||
[ -n "$reset_" ] && eval "$name_="
|
||
flag_=
|
||
fi
|
||
|
||
if i_="$(array_find options_ "$option_")"; then
|
||
options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}")
|
||
names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}")
|
||
flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}")
|
||
fi
|
||
options_=("${options_[@]}" "$option_")
|
||
names_=("${names_[@]}" "$name_")
|
||
flags_=("${flags_[@]}" "$flag_")
|
||
done
|
||
shift; shift
|
||
let shift_=$shift_+2
|
||
else
|
||
break
|
||
fi
|
||
done
|
||
|
||
i_=0
|
||
count_=${#options_[*]}
|
||
while [ $i_ -lt $count_ ]; do
|
||
option_="${options_[$i_]}"
|
||
flag_="${flags_[$i_]}"
|
||
i_=$(($i_ + 1))
|
||
|
||
flag_="${flag_%$}"
|
||
if [[ "$option_" == --* ]]; then
|
||
longopts_="${longopts_:+$longopts_,}${option_#--}$flag_"
|
||
elif [[ "$option_" == -* ]]; then
|
||
opts_="$opts_${option_#-}$flag_"
|
||
fi
|
||
done
|
||
|
||
return $shift_
|
||
}
|
||
function __po_check_options() {
|
||
local -a getopt_args_
|
||
getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@")
|
||
local args_
|
||
if args_="$(getopt -q "${getopt_args_[@]}")"; then
|
||
recho "$args_"
|
||
return 0
|
||
else
|
||
LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null
|
||
return 1
|
||
fi
|
||
}
|
||
function __po_process_options() {
|
||
while [ -n "$1" ]; do
|
||
if [ "$1" == -- ]; then
|
||
shift
|
||
break
|
||
elif [[ "$1" == -* ]]; then
|
||
local i_
|
||
let i_=0
|
||
for option_ in "${options_[@]}"; do
|
||
[ "$1" == "${options_[$i_]}" ] && break
|
||
let i_=$i_+1
|
||
done
|
||
name_="names_[$i_]"; name_="${!name_}"
|
||
flag_="flags_[$i_]"; flag_="${!flag_}"
|
||
function inc@ { eval "let $1=\$$1+1"; }
|
||
function res@ { set_var "$1" "${value_:-$2}"; }
|
||
function add@ { array_add "$1" "${value_:-$2}"; }
|
||
if [ -z "$name_" ]; then
|
||
ewarn "$1: option non reconnue, elle sera ignorée"
|
||
elif [[ "$flag_" == *\$ ]]; then
|
||
if [[ "$flag_" == :* ]]; then
|
||
value_="$2"; shift
|
||
function set@ { res@ "$@"; }
|
||
else
|
||
value_=
|
||
function set@ { inc@ "$@"; }
|
||
fi
|
||
eval "${name_#\$}"
|
||
elif [ "$flag_" == "" ]; then
|
||
if [[ "$name_" == *=* ]]; then
|
||
set_var "${name_%%=*}" "${name_#*=}"
|
||
else
|
||
inc@ "$name_"
|
||
fi
|
||
elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then
|
||
value_="$2"; shift
|
||
if [ "${name_%=}" != "$name_" ]; then
|
||
set_var "${name_%=}" "$value_"
|
||
elif [[ "$name_" == *=* ]]; then
|
||
set_var "${name_%%=*}" "${name_#*=}"
|
||
else
|
||
array_add "$name_" "$value_"
|
||
fi
|
||
fi
|
||
else
|
||
break
|
||
fi
|
||
shift
|
||
done
|
||
unset -f inc@ res@ add@ set@
|
||
[ -n "$destargs_" ] &&
|
||
set_array "$destargs_" @ "$@"
|
||
return 0
|
||
}
|
||
function parse_opts() {
|
||
|
||
|
||
|
||
local -a options_ names_ flags_ destargs_
|
||
local opts_ longopts_
|
||
__po_parse_optdescs "$@" || shift $?
|
||
local args_
|
||
if args_="$(__po_check_options "$@")"; then
|
||
eval "set -- $args_"
|
||
__po_process_options "$@"
|
||
else
|
||
[ -n "$destargs_" ] && set_var "$destargs_" "$args_"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
function parse_args_check() {
|
||
parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0
|
||
eerror "$args"
|
||
return 1
|
||
}
|
||
function parse_args() {
|
||
parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args"
|
||
}
|
||
|
||
HELP_DESC=
|
||
HELP_USAGE=
|
||
HELP_OPTIONS=
|
||
function __genparse_shortopt() {
|
||
local LC_COLLATE=C
|
||
local shortopt="${1//[^A-Z]}"
|
||
shortopt="$(strlower "${shortopt:0:1}")"
|
||
[ -n "$shortopt" ] && echo "$shortopt"
|
||
}
|
||
function genparse() {
|
||
|
||
local -a names descs vars options
|
||
local i desc var option name uname value shortopt
|
||
|
||
for var in "$@"; do
|
||
if [[ "$var" == *=* ]]; then
|
||
splitvar "$var" name value
|
||
shortopt="$(__genparse_shortopt "$name")"
|
||
option="$(strlower "$name")"
|
||
name="${option//-/_}"
|
||
array_add names "$name"
|
||
array_add descs "${shortopt:+-$shortopt, }--$option VALUE"
|
||
array_add vars "$(set_var_cmd "$name" "$value")"
|
||
array_add options "${shortopt:+-$shortopt:,}--$option: $name="
|
||
else
|
||
name="$var"
|
||
shortopt="$(__genparse_shortopt "$name")"
|
||
option="$(strlower "$name")"
|
||
name="${option//-/_}"
|
||
array_add names "$name"
|
||
array_add descs "${shortopt:+-$shortopt, }--$option"
|
||
array_add vars "$name="
|
||
array_add options "${shortopt:+-$shortopt,}--$option $name=1"
|
||
fi
|
||
done
|
||
|
||
echo -n 'function display_help() {
|
||
[ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE
|
||
$scriptname'
|
||
[ -n "$descs" ] && echo -n ' [options]'
|
||
echo '"'
|
||
if [ -n "$descs" ]; then
|
||
echo -n ' [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS'
|
||
i=0
|
||
while [ $i -lt ${#descs[*]} ]; do
|
||
name="${names[$i]}"
|
||
uname="$(strupper "$name")"
|
||
desc="${descs[$i]}"
|
||
echo -n "
|
||
\${HELP_${uname}_OPTION:- $desc\${HELP_${uname}_DESC:+
|
||
\${HELP_${uname}_DESC//
|
||
/
|
||
}}}"
|
||
i=$(($i + 1))
|
||
done
|
||
echo '"'
|
||
fi
|
||
echo ' uecho "${HELP_DESC:+$HELP_DESC
|
||
|
||
}$HELP_USAGE${HELP_OPTIONS:+
|
||
|
||
$HELP_OPTIONS}"
|
||
}
|
||
'
|
||
for var in "${vars[@]}"; do
|
||
echo "$var"
|
||
done
|
||
echo 'parse_opts "${PRETTYOPTS[@]}" \'
|
||
echo ' --help '\''$exit_with display_help'\'' \'
|
||
for option in "${options[@]}"; do
|
||
echo " $option \\"
|
||
done
|
||
echo ' @ args -- "$@" && set -- "${args[@]}" || die "$args"'
|
||
}
|
||
##@inc]base.args
|
||
##@inc[base.compat
|
||
## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x
|
||
##@inc[base.core
|
||
## Fonctions de base: fondement
|
||
uprovide base.core
|
||
|
||
function echo_() {
|
||
echo -n "$*"
|
||
}
|
||
function recho() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo "$first$@"
|
||
else
|
||
echo "$@"
|
||
fi
|
||
}
|
||
function recho_() {
|
||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||
echo -n -
|
||
local first="${1:1}"; shift
|
||
echo -n "$first$@"
|
||
else
|
||
echo -n "$@"
|
||
fi
|
||
}
|
||
function _qval() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\"/\\\"}"
|
||
s="${s//\$/\\\$}"
|
||
s="${s//\`/\\\`}"
|
||
recho_ "$s"
|
||
}
|
||
function should_quote() {
|
||
[ -z "$1" ] && return 0
|
||
local s="${*//[a-zA-Z0-9]/}"
|
||
s="${s//,/}"
|
||
s="${s//./}"
|
||
s="${s//+/}"
|
||
s="${s//\//}"
|
||
s="${s//-/}"
|
||
s="${s//_/}"
|
||
s="${s//=/}"
|
||
[ -n "$s" ]
|
||
}
|
||
function qval() {
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
}
|
||
function qvalm() {
|
||
if should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvalr() {
|
||
if [ -z "$*" ]; then
|
||
:
|
||
elif should_quote "$*"; then
|
||
echo -n \"
|
||
_qval "$@"
|
||
echo \"
|
||
else
|
||
recho "$*"
|
||
fi
|
||
}
|
||
function qvals() {
|
||
local arg first=1
|
||
for arg in "$@"; do
|
||
[ -z "$first" ] && echo -n " "
|
||
if should_quote "$arg"; then
|
||
echo -n \"
|
||
_qval "$arg"
|
||
echo -n \"
|
||
else
|
||
recho_ "$arg"
|
||
fi
|
||
first=
|
||
done
|
||
[ -z "$first" ] && echo
|
||
}
|
||
function qlines() {
|
||
sed "s/'/'\\\\''/g; s/.*/'&'/g"
|
||
}
|
||
function setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function _setv() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var=\"$(_qval "$*")\""
|
||
}
|
||
function echo_setv() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
echo "$__s_var=$(qvalr "$*")"
|
||
}
|
||
function setx() {
|
||
if [ "$1" == -a ]; then
|
||
shift
|
||
local __s_array="$1"; shift
|
||
if [[ "$__s_array" == *=* ]]; then
|
||
set -- "${__s_array#*=}" "$@"
|
||
__s_array="${__s_array%%=*}"
|
||
fi
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
else
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
eval "$__s_var="'"$("$@")"'
|
||
fi
|
||
}
|
||
function _setvx() {
|
||
local __s_var="$1"; shift
|
||
eval "$__s_var="'"$("$@")"'
|
||
}
|
||
function _setax() {
|
||
local __s_array="$1"; shift
|
||
eval "$__s_array=($("$@" | qlines))"
|
||
}
|
||
function evalx() {
|
||
local __e_val __e_arg __e_r=0
|
||
local -a __e_cmd
|
||
|
||
local __e_first=1
|
||
while [ $# -gt 0 ]; do
|
||
__e_cmd=()
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
[ "$__e_arg" == // ] && break
|
||
if [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
continue
|
||
fi
|
||
fi
|
||
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
|
||
done
|
||
|
||
if [ -n "$__e_first" ]; then
|
||
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
|
||
else
|
||
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
|
||
fi
|
||
__e_first=
|
||
done
|
||
[ -n "$__e_val" ] && echo "$__e_val"
|
||
return $__e_r
|
||
}
|
||
function setxx() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalx "$@"
|
||
}
|
||
function evalp() {
|
||
local __e_arg __e_cmd
|
||
|
||
while [ $# -gt 0 ]; do
|
||
__e_arg="$1"; shift
|
||
if [ "$__e_arg" == // ]; then
|
||
__e_cmd="$__e_cmd |"
|
||
continue
|
||
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
|
||
local __e_tmp="${__e_arg%//}"
|
||
if [ -z "${__e_tmp//\\/}" ]; then
|
||
__e_arg="${__e_arg#\\}"
|
||
fi
|
||
fi
|
||
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
|
||
done
|
||
eval "$__e_cmd"
|
||
}
|
||
function setxp() {
|
||
local -a __s_args
|
||
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
__s_args=("${__s_args[@]}" "$__s_var")
|
||
setx "${__s_args[@]}" evalp "$@"
|
||
}
|
||
function testx() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalx "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2x() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrx() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalx "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
function testp() {
|
||
local __t_op="$1"; shift
|
||
local __t_val="$(evalp "$@")"
|
||
[ $__t_op "$__t_val" ]
|
||
}
|
||
function test2p() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
[ "$__t_val1" $__t_op "$__t_val2" ]
|
||
}
|
||
function testrp() {
|
||
local __t_val1="$1"; shift
|
||
local __t_op="$1"; shift
|
||
local __t_val2="$(evalp "$@")"
|
||
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
|
||
}
|
||
|
||
function err2out() {
|
||
"$@" 2>&1
|
||
}
|
||
##@inc]base.core
|
||
##@inc[base.num
|
||
## Fonctions de base: gestion des valeurs numériques
|
||
uprovide base.num
|
||
|
||
function isnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function ispnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function isrnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//./}"
|
||
v="${v//,/}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
##@inc]base.num
|
||
##@inc[base.bool
|
||
## Fonctions de base: valeurs booléennes
|
||
##@inc[base.num
|
||
## Fonctions de base: gestion des valeurs numériques
|
||
uprovide base.num
|
||
|
||
function isnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function ispnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
function isrnum() {
|
||
[ ${#1} -gt 0 ] || return 1
|
||
local v="$1"
|
||
v="${v#-}"
|
||
v="${v//./}"
|
||
v="${v//,/}"
|
||
v="${v//[0-9]/}"
|
||
[ -z "$v" ]
|
||
}
|
||
##@inc]base.num
|
||
uprovide base.bool
|
||
urequire base.num
|
||
|
||
function is_yes() {
|
||
case "${1,,}" in
|
||
o|oui|y|yes|v|vrai|t|true|on) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -ne 0 ] && return 0
|
||
return 1
|
||
}
|
||
function is_no() {
|
||
case "${1,,}" in
|
||
n|non|no|f|faux|false|off) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -eq 0 ] && return 0
|
||
return 1
|
||
}
|
||
function yesval() {
|
||
is_yes "$1" && echo 1
|
||
}
|
||
|
||
function setb() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
local __s_r
|
||
if "$@" >/dev/null; then
|
||
eval "$__s_var=1"
|
||
else
|
||
__s_r=$?
|
||
eval "$__s_var="
|
||
return $__s_r
|
||
fi
|
||
}
|
||
function _setb() {
|
||
local __s_var="$1"; shift
|
||
if "$@" >/dev/null; then
|
||
eval "$__s_var=1"
|
||
else
|
||
eval "$__s_var="
|
||
fi
|
||
}
|
||
|
||
function evalb() {
|
||
if evalx "$@" >/dev/null; then
|
||
echo 1
|
||
else
|
||
return $?
|
||
fi
|
||
}
|
||
function setxb() {
|
||
local __s_var="$1"; shift
|
||
if [[ "$__s_var" == *=* ]]; then
|
||
set -- "${__s_var#*=}" "$@"
|
||
__s_var="${__s_var%%=*}"
|
||
fi
|
||
setx "$__s_var" evalb "$@"
|
||
}
|
||
##@inc]base.bool
|
||
##@inc[base.quote
|
||
## Fonctions de base: protection de valeurs chaine
|
||
uprovide base.quote
|
||
urequire base.core
|
||
|
||
function _qawk() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\"/\\\"}"
|
||
s="${s//
|
||
/\\n}"
|
||
recho_ "$s"
|
||
}
|
||
function qawk() {
|
||
echo -n \"
|
||
_qawk "$@"
|
||
echo \"
|
||
}
|
||
function qseds() {
|
||
local s="$*"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\//\\/}"
|
||
recho "$s"
|
||
}
|
||
function _qform() {
|
||
local s="$*"
|
||
s="${s//\%/%25}"
|
||
s="${s//+/%2B}"
|
||
s="${s//&/%26}"
|
||
s="${s//=/%3D}"
|
||
s="${s// /+}"
|
||
recho_ "$s"
|
||
}
|
||
function qform() {
|
||
local s="$*"
|
||
if [[ "$s" == *=* ]]; then
|
||
_qform "${s%%=*}"
|
||
echo -n =
|
||
_qform "${s#*=}"
|
||
echo
|
||
else
|
||
_qform "$s"
|
||
echo
|
||
fi
|
||
}
|
||
##@inc]base.quote
|
||
uprovide base.compat
|
||
urequire base.core base.num base.bool base.quote
|
||
|
||
|
||
function setx2() { setxx "$@"; }
|
||
function rawecho() { recho "$@"; }
|
||
function rawecho_() { recho_ "$@"; }
|
||
function quote_arg() { _qval "$@"; }
|
||
function quoted_arg() { qvalm "$@"; }
|
||
function quoted_args() { qvals "$@"; }
|
||
function set_var() { setv "$@"; }
|
||
function set_var_cmd() { echo_setv "$@"; }
|
||
function set_var_literal() { eval "$1=$2"; }
|
||
|
||
function quote_awk() { _qawk "$@"; }
|
||
function quoted_awk() { qawk "$@"; }
|
||
function quote_seds() { qseds "$@"; }
|
||
function quote_form() { _qform "$@"; }
|
||
function quoted_form() { qform "$@"; }
|
||
|
||
|
||
if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then
|
||
function strlower() { tr A-Z a-z <<<"$*"; }
|
||
function strlower1() {
|
||
local str="$*"
|
||
local h="${str:0:1}" r="${str:1}"
|
||
echo "$(tr A-Z a-z <<<"$h")$r"
|
||
}
|
||
function strlowers() {
|
||
local -a vs; local v
|
||
for v in "$@"; do
|
||
vs=("${vs[@]}" "$(strlower1 "$v")")
|
||
done
|
||
echo "${vs[*]}"
|
||
}
|
||
function strupper() { tr a-z A-Z <<<"$*"; }
|
||
function strupper1() {
|
||
local str="$*"
|
||
local h="${str:0:1}" r="${str:1}"
|
||
echo "$(tr a-z A-Z <<<"$h")$r"
|
||
}
|
||
function struppers() {
|
||
local -a vs; local v
|
||
for v in "$@"; do
|
||
vs=("${vs[@]}" "$(strupper1 "$v")")
|
||
done
|
||
echo "${vs[*]}"
|
||
}
|
||
|
||
function is_yes() {
|
||
case "$1" in
|
||
o|oui|y|yes|v|vrai|t|true|on) return 0;;
|
||
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -ne 0 ] && return 0
|
||
case "$(strlower "$1")" in
|
||
o|oui|y|yes|v|vrai|t|true|on) return 0;;
|
||
esac
|
||
return 1
|
||
}
|
||
function is_no() {
|
||
case "$1" in
|
||
n|non|no|f|faux|false|off) return 0;;
|
||
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
|
||
esac
|
||
isnum "$1" && [ "$1" -eq 0 ] && return 0
|
||
case "$(strlower "$1")" in
|
||
n|non|no|f|faux|false|off) return 0;;
|
||
esac
|
||
return 1
|
||
}
|
||
fi
|
||
##@inc]base.compat
|
||
uprovide base
|
||
urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.compat
|
||
|
||
UNAME_SYSTEM=`uname -s`
|
||
[ "${UNAME_SYSTEM#CYGWIN}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Cygwin
|
||
[ "${UNAME_SYSTEM#MINGW32}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Mingw
|
||
UNAME_MACHINE=`uname -m`
|
||
if [ -n "$UTOOLS_CHROOT" ]; then
|
||
[ -n "$UTOOLS_UNAME_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
|
||
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
|
||
fi
|
||
|
||
function setyesval() {
|
||
is_yes "$2" && set_var "$1" 1 || set_var "$1" ""
|
||
}
|
||
function normyesval() {
|
||
is_yes "${2:-"${!1}"}" && set_var "$1" 1 || set_var "$1" ""
|
||
}
|
||
function normyesvals() {
|
||
local __nyv_yesvar
|
||
for __nyv_yesvar in "$@"; do
|
||
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
|
||
done
|
||
}
|
||
function quote_in() {
|
||
sed 's/\\/\\\\/g
|
||
s/"/\\"/g
|
||
s/\$/\\$/g
|
||
s/`/\\`/g'
|
||
}
|
||
function quote_sin() {
|
||
sed "s/'/'\\\\''/g"
|
||
}
|
||
function quote_sarg() {
|
||
quote_sin <<<"$1"
|
||
}
|
||
function quoted_sarg() {
|
||
echo "'$(quote_sarg "$1")'"
|
||
}
|
||
function quoted_sargs() {
|
||
local a s
|
||
for a in "$@"; do
|
||
s="${s:+$s }$(quoted_sarg "$a")"
|
||
done
|
||
rawecho "$s"
|
||
}
|
||
|
||
function set_array_cmd() {
|
||
[ $# -eq 1 ] && set -- "$1" "$1"
|
||
local __sac_s __sac_v __sac_f
|
||
__sac_s="$1=("; shift
|
||
if [ "$1" == "@" ]; then
|
||
shift
|
||
else
|
||
eval "set -- \"\${$1[@]}\""
|
||
fi
|
||
__sac_f=1
|
||
for __sac_v in "$@"; do
|
||
[ -n "$__sac_f" ] && __sac_f= || __sac_s="$__sac_s "
|
||
__sac_s="$__sac_s$(quoted_arg "$__sac_v")"
|
||
done
|
||
__sac_s="$__sac_s)"
|
||
echo "$__sac_s"
|
||
}
|
||
function set_array() {
|
||
eval "$(set_array_cmd "$@")"
|
||
}
|
||
function array_count() {
|
||
eval "echo \${#$1[*]}"
|
||
}
|
||
function array_isempty() {
|
||
[ $(array_count "$1") -eq 0 ]
|
||
}
|
||
function array_new() {
|
||
eval "$1=()"
|
||
}
|
||
function array_add() {
|
||
local __aa_a="$1"; shift
|
||
eval "$__aa_a=(\"\${$__aa_a[@]}\" \"\$@\")"
|
||
}
|
||
function array_ins() {
|
||
local __aa_a="$1"; shift
|
||
eval "$__aa_a=(\"\$@\" \"\${$__aa_a[@]}\")"
|
||
}
|
||
function array_del() {
|
||
local __ad_v
|
||
local -a __ad_vs
|
||
eval 'for __ad_v in "${'"$1"'[@]}"; do
|
||
if [ "$__ad_v" != '"$(quoted_arg "$2")"' ]; then
|
||
array_add __ad_vs "$__ad_v"
|
||
fi
|
||
done'
|
||
array_copy "$1" __ad_vs
|
||
}
|
||
function array_addu() {
|
||
local __as_v
|
||
eval 'for __as_v in "${'"$1"'[@]}"; do
|
||
if [ "$__as_v" == '"$(quoted_arg "$2")"' ]; then
|
||
return 1
|
||
fi
|
||
done'
|
||
array_add "$1" "$2"
|
||
return 0
|
||
}
|
||
function array_set() {
|
||
array_addu "$@"
|
||
}
|
||
function array_insu() {
|
||
local __as_v
|
||
eval 'for __as_v in "${'"$1"'[@]}"; do
|
||
if [ "$__as_v" == '"$(quoted_arg "$2")"' ]; then
|
||
return 1
|
||
fi
|
||
done'
|
||
array_ins "$1" "$2"
|
||
return 0
|
||
}
|
||
function array_fillrange() {
|
||
local -a __af_vs
|
||
local __af_i="${2:-1}" __af_to="${3:-10}" __af_step="${4:-1}"
|
||
while [ "$__af_i" -le "$__af_to" ]; do
|
||
__af_vs=("${__af_vs[@]}" "$__af_i")
|
||
__af_i=$(($__af_i + $__af_step))
|
||
done
|
||
array_copy "$1" __af_vs
|
||
}
|
||
function array_eq() {
|
||
local -a __ae_a1 __ae_a2
|
||
array_copy __ae_a1 "$1"
|
||
array_copy __ae_a2 "$2"
|
||
[ ${#__ae_a1[*]} -eq ${#__ae_a2[*]} ] || return 1
|
||
local __ae_v __ae_i=0
|
||
for __ae_v in "${__ae_a1[@]}"; do
|
||
[ "$__ae_v" == "${__ae_a2[$__ae_i]}" ] || return 1
|
||
__ae_i=$(($__ae_i + 1))
|
||
done
|
||
return 0
|
||
}
|
||
function array_contains() {
|
||
local __ac_v
|
||
eval 'for __ac_v in "${'"$1"'[@]}"; do
|
||
if [ "$__ac_v" == '"$(quoted_arg "$2")"' ]; then
|
||
return 0
|
||
fi
|
||
done'
|
||
return 1
|
||
}
|
||
function array_find() {
|
||
local __af_i __af_v
|
||
__af_i=0
|
||
eval 'for __af_v in "${'"$1"'[@]}"; do
|
||
if [ "$__af_v" == '"$(quoted_arg "$2")"' ]; then
|
||
if [ -n "$3" ]; then
|
||
echo "${'"$3"'[$__af_i]}"
|
||
else
|
||
echo "$__af_i"
|
||
fi
|
||
return 0
|
||
fi
|
||
__af_i=$(($__af_i + 1))
|
||
done'
|
||
return 1
|
||
}
|
||
function array_reverse() {
|
||
local -a __ar_vs
|
||
local __ar_v
|
||
array_copy __ar_vs "$1"
|
||
array_new "$1"
|
||
for __ar_v in "${__ar_vs[@]}"; do
|
||
array_ins "$1" "$__ar_v"
|
||
done
|
||
}
|
||
|
||
function array_replace() {
|
||
local __ar_sn="$1"; shift
|
||
local __ar_f="$1"; shift
|
||
local -a __ar_s __ar_d
|
||
local __ar_v
|
||
array_copy __ar_s "$__ar_sn"
|
||
for __ar_v in "${__ar_s[@]}"; do
|
||
if [ "$__ar_v" == "$__ar_f" ]; then
|
||
__ar_d=("${__ar_d[@]}" "$@")
|
||
else
|
||
__ar_d=("${__ar_d[@]}" "$__ar_v")
|
||
fi
|
||
done
|
||
array_copy "$__ar_sn" __ar_d
|
||
}
|
||
function array_each() {
|
||
local __ae_an="$1"; shift
|
||
local __ae_f="$1"; shift
|
||
local -a __ae_a
|
||
local __ae_v
|
||
array_copy __ae_a "$__ae_an"
|
||
for __ae_v in "${__ae_a[@]}"; do
|
||
"$__ae_f" "$__ae_v" "$@"
|
||
done
|
||
}
|
||
function array_map() {
|
||
local __am_an="$1"; shift
|
||
local __am_f="$1"; shift
|
||
local -a __am_a __am_vs
|
||
local __am_v
|
||
array_copy __am_a "$__am_an"
|
||
for __am_v in "${__am_a[@]}"; do
|
||
__am_vs=("${__am_vs[@]}" "$("$__am_f" "$__am_v" "$@")")
|
||
done
|
||
array_copy "$__am_an" __am_vs
|
||
}
|
||
function first_value() {
|
||
eval "rawecho \"\${$1[@]:0:1}\""
|
||
}
|
||
function last_value() {
|
||
eval "rawecho \"\${$1[@]:\$((-1)):1}\""
|
||
}
|
||
function array_copy() {
|
||
eval "$1=(\"\${$2[@]}\")"
|
||
}
|
||
function array_copy_firsts() {
|
||
eval "$1=(\"\${${2:-$1}[@]:0:\$((\${#${2:-$1}[@]}-1))}\")"
|
||
}
|
||
function array_del_last() {
|
||
array_copy_firsts "$1"
|
||
}
|
||
function array_copy_lasts() {
|
||
eval "$1=(\"\${${2:-$1}[@]:1}\")"
|
||
}
|
||
function array_del_first() {
|
||
array_copy_lasts "$1"
|
||
}
|
||
function array_extend() {
|
||
eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")"
|
||
}
|
||
function array_extendu() {
|
||
local __ae_v __ae_s=1
|
||
eval 'for __ae_v in "${'"$2"'[@]}"; do
|
||
array_addu "$1" "$__ae_v" && __ae_s=0
|
||
done'
|
||
return "$__ae_s"
|
||
}
|
||
function array_extend_firsts() {
|
||
eval "$1=(\"\${$1[@]}\" \"\${$2[@]:0:\$((\${#$2[@]}-1))}\")"
|
||
}
|
||
function array_extend_lasts() {
|
||
eval "$1=(\"\${$1[@]}\" \"\${$2[@]:1}\")"
|
||
}
|
||
function array_xsplit() {
|
||
eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" '
|
||
{
|
||
gsub(/'\''/, "'\'\\\\\'\''")
|
||
print "'\''" $0 "'\''"
|
||
}'))" #"
|
||
}
|
||
function array_split() {
|
||
eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" '
|
||
/^$/ { next }
|
||
{
|
||
gsub(/'\''/, "'\'\\\\\'\''")
|
||
print "'\''" $0 "'\''"
|
||
}'))" #"
|
||
}
|
||
function array_from_path() {
|
||
array_split "$1" "$2" ":"
|
||
}
|
||
function array_from_xlines() {
|
||
eval "$1=($(recho_ "$2" | _nl2lf | awk '
|
||
{
|
||
gsub(/'\''/, "'\'\\\\\'\''")
|
||
print "'\''" $0 "'\''"
|
||
}'))" #"
|
||
}
|
||
function array_from_lines() {
|
||
eval "$1=($(recho_ "$2" | _nl2lf | awk '
|
||
/^$/ { next }
|
||
{
|
||
gsub(/'\''/, "'\'\\\\\'\''")
|
||
print "'\''" $0 "'\''"
|
||
}'))" #"
|
||
}
|
||
function array_join() {
|
||
local __aj_an __aj_l __aj_j __aj_s="${2:-,}" __aj_pf __aj_sf
|
||
if [ "$1" == "@" ]; then
|
||
__aj_an="\$@"
|
||
shift; shift
|
||
else
|
||
__aj_an="\${$1[@]}"
|
||
__aj_pf="$4"
|
||
__aj_sf="$5"
|
||
fi
|
||
eval 'for __aj_l in "'"$__aj_an"'"; do
|
||
__aj_j="${__aj_j:+$__aj_j'"$__aj_s"'}$__aj_pf$__aj_l$__aj_sf"
|
||
done'
|
||
if [ -n "$__aj_j" ]; then
|
||
rawecho "$__aj_j"
|
||
elif [ "$__aj_an" != "\$@" -a -n "$3" ]; then
|
||
rawecho "$3"
|
||
fi
|
||
}
|
||
function array_mapjoin() {
|
||
local __amj_src="$1" __amj_func="$2" __amj_sep="$3"
|
||
shift; shift; shift
|
||
if [ "$__amj_src" == "@" ]; then
|
||
local -a __amj_tmpsrc
|
||
__amj_tmpsrc=("$@")
|
||
__amj_src=__amj_tmpsrc
|
||
set --
|
||
fi
|
||
local -a __amj_tmp
|
||
array_copy __amj_tmp "$__amj_src"
|
||
array_map __amj_tmp "$__amj_func"
|
||
array_join __amj_tmp "$__amj_sep" "$@"
|
||
}
|
||
function array_to_lines() {
|
||
array_join "$1" "
|
||
" "$2" "$3" "$4"
|
||
}
|
||
function array_to_path() {
|
||
array_join "$1" ":" "$2" "$3" "$4"
|
||
}
|
||
function array_fix_paths() {
|
||
local __afp_an="$1" __afp_s="${2:-:}"
|
||
local -a __afp_vs
|
||
local __afp_v
|
||
array_copy __afp_vs "$__afp_an"
|
||
array_new "$__afp_an"
|
||
for __afp_v in "${__afp_vs[@]}"; do
|
||
array_split __afp_v "$__afp_v" "$__afp_s"
|
||
array_extend "$__afp_an" __afp_v
|
||
done
|
||
}
|
||
|
||
|
||
function get_date_rfc822() {
|
||
LC_TIME=C date +"%a, %d %b %Y %H:%M:%S %Z"
|
||
}
|
||
function get_date_fr() {
|
||
LC_TIME=C date +"%d/%m/%Y"
|
||
}
|
||
function get_time_fr() {
|
||
LC_TIME=C date +"%Hh%M"
|
||
}
|
||
function parse_date() {
|
||
local value="$1" type="${2:-date}"
|
||
local now="$(awk 'BEGIN { print mktime(strftime("%Y %m %d 00 00 00 +0400")) }')"
|
||
case "$value" in
|
||
+*)
|
||
value="$(($now + ${value#+} * 86400))"
|
||
;;
|
||
*)
|
||
value="$(<<<"$value" awk -F/ '{
|
||
nd = strftime("%d"); nm = strftime("%m"); ny = strftime("%Y")
|
||
d = $1 + 0; if (d < 1) d = nd;
|
||
m = $2 + 0; if (m < 1) m = nm;
|
||
if ($3 == "") y = ny;
|
||
else { y = $3 + 0; if (y < 100) y = y + 2000; }
|
||
print mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d));
|
||
}')"
|
||
esac
|
||
case "$type" in
|
||
d|date) awk '{ print strftime("%d/%m/%Y", $0 + 0) }' <<<"$value";;
|
||
l|ldap) awk '{ print strftime("%Y%m%d%H%M%S+0400", $0 + 0) }' <<<"$value";;
|
||
m|mysql) awk '{ print strftime("%Y-%m-%d", $0 + 0) }' <<<"$value";;
|
||
*)
|
||
rawecho "$value"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
|
||
function udelpath() {
|
||
local _qdir="${1//\//\\/}"
|
||
eval "export ${2:-PATH}; ${2:-PATH}"'="${'"${2:-PATH}"'#$1:}"; '"${2:-PATH}"'="${'"${2:-PATH}"'%:$1}"; '"${2:-PATH}"'="${'"${2:-PATH}"'//:$_qdir:/:}"; [ "$'"${2:-PATH}"'" == "$1" ] && '"${2:-PATH}"'='
|
||
}
|
||
function uaddpath() {
|
||
local _qdir="${1//\//\\/}"
|
||
eval "export ${2:-PATH}; "'[ "${'"${2:-PATH}"'#$1:}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'%:$1}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'//:$_qdir:/:}" == "$'"${2:-PATH}"'" -a "$'"${2:-PATH}"'" != "$1" ] && '"${2:-PATH}"'="${'"${2:-PATH}"':+$'"${2:-PATH}"':}$1"'
|
||
}
|
||
function uinspathm() {
|
||
local _qdir="${1//\//\\/}"
|
||
eval "export ${2:-PATH}; "'[ "${'"${2:-PATH}"'#$1:}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'%:$1}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'//:$_qdir:/:}" == "$'"${2:-PATH}"'" -a "$'"${2:-PATH}"'" != "$1" ] && '"${2:-PATH}"'="$1${'"${2:-PATH}"':+:$'"${2:-PATH}"'}"'
|
||
}
|
||
function uinspath() {
|
||
udelpath "$@"
|
||
uinspathm "$@"
|
||
}
|
||
|
||
function withpath() {
|
||
[ "${1#./}" != "$1" -o "${1#../}" != "$1" -o "${1#/}" != "$1" ]
|
||
}
|
||
function withext() {
|
||
local basename="$(basename -- "$1")"
|
||
[ "${basename%.*}" != "$basename" ]
|
||
}
|
||
function normpath() {
|
||
local -a parts
|
||
local part ap
|
||
array_split parts "$1" /
|
||
if [ "${1#/}" != "$1" ]; then
|
||
ap=/
|
||
elif [ -n "$2" ]; then
|
||
ap="$2"
|
||
else
|
||
ap="$(pwd)"
|
||
fi
|
||
for part in "${parts[@]}"; do
|
||
if [ "$part" == "." ]; then
|
||
continue
|
||
elif [ "$part" == ".." ]; then
|
||
ap="${ap%/*}"
|
||
[ -n "$ap" ] || ap=/
|
||
else
|
||
[ "$ap" != "/" ] && ap="$ap/"
|
||
ap="$ap$part"
|
||
fi
|
||
done
|
||
rawecho "$ap"
|
||
}
|
||
function abspath() {
|
||
local ap="$1"
|
||
if [ "${ap#/}" != "$ap" ]; then
|
||
__normpath "$ap" && return
|
||
else
|
||
local cwd
|
||
if [ -n "$2" ]; then
|
||
cwd="$(abspath "$2")"
|
||
else
|
||
cwd="$(pwd)"
|
||
fi
|
||
ap="$cwd/$ap"
|
||
__normpath "$ap" && return
|
||
fi
|
||
normpath "$ap"
|
||
}
|
||
function __normpath() {
|
||
if [ -d "$1" ]; then
|
||
if [ -x "$1" ]; then
|
||
(cd "$1"; pwd)
|
||
return 0
|
||
fi
|
||
elif [ -f "$1" ]; then
|
||
local dn="$(dirname -- "$1")" bn="$(basename -- "$1")"
|
||
if [ -x "$dn" ]; then
|
||
(cd "$dn"; echo "$(pwd)/$bn")
|
||
return 0
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
function parentdirs() {
|
||
array_new "$1"
|
||
local __pd_d="$(abspath "$2")"
|
||
if [[ "$3" == r* ]]; then
|
||
while [ "$__pd_d" != "/" ]; do
|
||
array_ins "$1" "$__pd_d"
|
||
__pd_d="$(dirname "$__pd_d")"
|
||
done
|
||
else
|
||
while [ "$__pd_d" != "/" ]; do
|
||
array_add "$1" "$__pd_d"
|
||
__pd_d="$(dirname "$__pd_d")"
|
||
done
|
||
fi
|
||
}
|
||
function ppath() {
|
||
local path="$1" cwd="$2"
|
||
|
||
path="$(abspath "$path")" # essayer de normaliser le chemin
|
||
[ -n "$cwd" ] || cwd="$(pwd)"
|
||
|
||
[ "$path" = "$cwd" ] && path="."
|
||
[ "$cwd" != "/" -a "$cwd" != "$HOME" ] && path="${path/#$cwd\//}"
|
||
path="${path/#$HOME/~}"
|
||
|
||
rawecho "$path"
|
||
}
|
||
function relpath() {
|
||
local p="$(abspath "$1" "$3")" cwd="$2"
|
||
if [ -z "$cwd" ]; then
|
||
cwd="$(pwd)"
|
||
else
|
||
cwd="$(abspath "$cwd" "$3")"
|
||
fi
|
||
if [ "$p" == "$cwd" ]; then
|
||
echo ""
|
||
elif [ "${p#$cwd/}" != "$p" ]; then
|
||
rawecho "${p#$cwd/}"
|
||
else
|
||
local rp
|
||
while [ -n "$cwd" -a "${p#$cwd/}" == "$p" ]; do
|
||
rp="${rp:+$rp/}.."
|
||
cwd="${cwd%/*}"
|
||
done
|
||
rp="$rp/${p#$cwd/}"
|
||
echo "${rp%//}"
|
||
fi
|
||
}
|
||
function relpathx() {
|
||
local p="$(relpath "$@")"
|
||
if [ -z "$p" ]; then
|
||
echo .
|
||
elif [ "${p#../}" != "$p" -o "${p#./}" != "$p" ]; then
|
||
echo "$p"
|
||
else
|
||
echo "./$p"
|
||
fi
|
||
}
|
||
function withinpath() {
|
||
local b="$1" p="$2" strict="${3:-N}"
|
||
b="$(abspath "$b")"
|
||
p="$(abspath "$p")"
|
||
if is_yes "$strict"; then
|
||
[ "${p#$b/}" != "$p" ]
|
||
else
|
||
[ "$p" == "$b" -o "${p#$b/}" != "$p" ]
|
||
fi
|
||
}
|
||
function safe_abspath() {
|
||
local p="$1" ba="$2" br="$3"
|
||
if [ -n "$ba" ]; then
|
||
ba="$(abspath "$ba")"
|
||
else
|
||
ba="$(pwd)"
|
||
fi
|
||
[ -n "$br" ] || br="$ba"
|
||
br="$(abspath "$br" "$ba")"
|
||
p="$(abspath "$p" "$ba")"
|
||
if [ "$p" == "$br" -o "${p#$br/}" != "$p" ]; then
|
||
echo "$p"
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
function safe_relpath() {
|
||
local p
|
||
if p="$(safe_abspath "$1" "$2" "$3")"; then
|
||
relpath "$p" "$2" "$(pwd)"
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
function splitwcs() {
|
||
local __sw_p="$1"
|
||
local __sw_dd="${2:-basedir}" __sw_df="${3:-filespec}" __sw_part __sw_d __sw_f
|
||
local -a __sw_parts
|
||
array_split __sw_parts "$__sw_p" "/"
|
||
for __sw_part in "${__sw_parts[@]}"; do
|
||
if [[ "$__sw_part" == *\** ]] || [[ "$__sw_part" == *\?* ]] || [ -n "$__sw_f" ]; then
|
||
__sw_f="${__sw_f:+$__sw_f/}$__sw_part"
|
||
else
|
||
__sw_d="${__sw_d:+$__sw_d/}$__sw_part"
|
||
fi
|
||
done
|
||
[ "${__sw_p#/}" != "$__sw_p" ] && __sw_d="/$__sw_d"
|
||
set_var "$__sw_dd" "$__sw_d"
|
||
set_var "$__sw_df" "$__sw_f"
|
||
}
|
||
function deref() {
|
||
local OENC="$UTF8"
|
||
|
||
local max_deref=50
|
||
local file="$1"
|
||
local basedir link
|
||
while [ -L "$file" ]; do
|
||
basedir="$(dirname "$file")"
|
||
link="$(readlink "$file")"
|
||
if first_char_is "$link" "/"; then
|
||
file="$link"
|
||
else
|
||
file="$basedir/$link"
|
||
fi
|
||
|
||
max_deref=$(($max_deref - 1))
|
||
[ $max_deref -eq 0 ] && die "Plus de 50 indirection. Le lien $file est-il récursif?"
|
||
done
|
||
abspath "$file"
|
||
}
|
||
function readlinkm() {
|
||
readlink -m "$1"
|
||
}
|
||
function path_if_test() {
|
||
local op="$1"; shift
|
||
local file="$1"; shift
|
||
local rel="$1" reldir=; shift
|
||
if beginswith "$rel" relative; then
|
||
reldir="${rel#relative}"
|
||
if beginswith "$reldir" :; then
|
||
reldir="${reldir#:}"
|
||
if [ -n "$reldir" ]; then
|
||
reldir="${reldir}/"
|
||
fi
|
||
else
|
||
reldir=
|
||
fi
|
||
else
|
||
rel=
|
||
fi
|
||
|
||
while [ -n "$1" ]; do
|
||
local basedir="$1"
|
||
if [ $op "$basedir/$file" ]; then
|
||
if [ -n "$rel" ]; then
|
||
rawecho "$reldir$file"
|
||
else
|
||
rawecho "$basedir/$file"
|
||
fi
|
||
break
|
||
fi
|
||
shift
|
||
done
|
||
}
|
||
|
||
function get_nblines() {
|
||
[ -f "$1" ] && sed -ne '$=' "$1" || echo 0
|
||
}
|
||
function mktempf() {
|
||
mktemp "${1:-"$TMPDIR/tmp.XXXXXX"}"
|
||
}
|
||
function mktempd() {
|
||
mktemp -d "${1:-"$TMPDIR/tmp.XXXXXX"}"
|
||
}
|
||
function mkdirof() {
|
||
mkdir -p "$(dirname -- "$1")"
|
||
}
|
||
function cp_a() {
|
||
/bin/cp -a "$@"
|
||
}
|
||
function cp_R() {
|
||
/bin/cp -pR "$@"
|
||
}
|
||
function quietgrep() {
|
||
grep -q "$@" 2>/dev/null
|
||
}
|
||
function quietdiff() {
|
||
diff -q "$@" >&/dev/null
|
||
}
|
||
function testsame() {
|
||
quietdiff "$@"
|
||
}
|
||
function testdiff() {
|
||
! quietdiff "$@"
|
||
}
|
||
function testupdated() {
|
||
if [ -f "$2" ]; then
|
||
testdiff "$1" "$2"
|
||
else
|
||
return 0
|
||
fi
|
||
}
|
||
function testnewer() {
|
||
test ! -e "$2" -o "$1" -nt "$2"
|
||
}
|
||
function ps_all() {
|
||
ps -axww
|
||
}
|
||
function progexists() {
|
||
test -n "$1" -a -x "$(which "$1" 2>/dev/null)"
|
||
}
|
||
function has_python() {
|
||
progexists python
|
||
}
|
||
function has_gawk() {
|
||
progexists gawk
|
||
}
|
||
function is_root() {
|
||
test `id -u` -eq 0
|
||
}
|
||
function source_ifexists() {
|
||
if [ -f "$1" ]; then source "$1" || die; fi
|
||
}
|
||
function little_sleep {
|
||
LC_NUMERIC=C sleep 0.1
|
||
}
|
||
function random_sleep {
|
||
sleep $(($RANDOM % ${1:-1800}))
|
||
}
|
||
function is_running() {
|
||
kill -0 "$1" >&/dev/null
|
||
}
|
||
function sedi() {
|
||
sed -i "$@"
|
||
}
|
||
function csort() {
|
||
LANG=C sort "$@"
|
||
}
|
||
function lsort() { sort "$@"; }
|
||
function cgrep() {
|
||
LANG=C grep "$@"
|
||
}
|
||
function lgrep() { grep "$@"; }
|
||
function csed() {
|
||
LANG=C sed "$@"
|
||
}
|
||
function lsed() { sed "$@"; }
|
||
function cawk() {
|
||
LANG=C awk "$@"
|
||
}
|
||
function lawk() { awk "$@"; }
|
||
function cdiff() {
|
||
LANG=C diff "$@"
|
||
}
|
||
function ldiff() { diff "$@"; }
|
||
|
||
|
||
function fix_mode() {
|
||
local file="$1"
|
||
[ -f "$file" ] || touch "$file" || return 1
|
||
if [ ! -w "$file" ]; then
|
||
local mode="$(stat -c %a "$file")"
|
||
chmod ${mode:0:${#mode}-3}6${mode:${#mode}-2:2} "$file"
|
||
echo "$mode"
|
||
fi
|
||
}
|
||
function unfix_mode() {
|
||
[ -n "$2" ] && chmod "$2" "$1"
|
||
}
|
||
function get_mode() {
|
||
[ -f "$1" ] || touch "$1" || return 1
|
||
stat -c %a "$1"
|
||
}
|
||
function rm_maybe() {
|
||
local parse_opts=1 arg rm
|
||
for arg in "$@"; do
|
||
if [ -n "$parse_opts" ]; then
|
||
if [ "$arg" == "--" ]; then
|
||
parse_opts=
|
||
elif [[ "$arg" == "-*" ]]; then
|
||
continue
|
||
elif [ -n "$arg" ]; then
|
||
rm=1
|
||
break
|
||
fi
|
||
elif [ -n "$arg" ]; then
|
||
rm=1
|
||
break
|
||
fi
|
||
done
|
||
[ -n "$rm" ] && /bin/rm "$@"
|
||
}
|
||
__CPDIR_RSYNC_SLOW=1 # synchro potentiellement plus lente, mais plus fidèle (option -c)
|
||
__CPDIR_RSYNC_ARGS=(-q)
|
||
function cpdir() {
|
||
|
||
if progexists rsync; then
|
||
[ -d "$2" ] || mkdir -p "$2" || return 1
|
||
if [ -d "$1" ]; then
|
||
rsync -a ${__CPDIR_RSYNC_SLOW:+-c} "${__CPDIR_RSYNC_ARGS[@]}" "$1/" "$2/"
|
||
else
|
||
rsync -a ${__CPDIR_RSYNC_SLOW:+-c} "${__CPDIR_RSYNC_ARGS[@]}" "$1" "$2/"
|
||
fi
|
||
else
|
||
__cpdir "$@"
|
||
fi
|
||
}
|
||
function __cpdir() {
|
||
local src="$1" dest="$2" method="${3:-cp_a}"
|
||
|
||
if [ -d "$src" ]; then
|
||
[ -d "$dest" ] || mkdir -p "$dest" || return 1
|
||
|
||
local prevdir="$(pwd)"
|
||
|
||
dest="$(abspath "$dest")"
|
||
cd "$src"
|
||
if [ -n "$(/bin/ls -a1)" ]; then
|
||
[ -n "$(/bin/ls -1)" ] && "$method" * "$dest"
|
||
local i
|
||
for i in .*; do
|
||
[ "$i" == "." -o "$i" == ".." ] && continue
|
||
"$method" "$i" "$dest"
|
||
done
|
||
fi
|
||
cd "$prevdir"
|
||
else
|
||
if [ -f "$dest" ]; then
|
||
"$method" "$src" "$dest"
|
||
elif [ -d "$dest" ]; then
|
||
"$method" "$src" "$dest"
|
||
else
|
||
mkdir -p "$dest"
|
||
"$method" "$src" "$dest"
|
||
fi
|
||
fi
|
||
}
|
||
__CPNOVCS_RSYNC_SLOW=1 # synchro potentiellement plus lente, mais plus fidèle (option -c)
|
||
__CPNOVCS_RSYNC_ARGS=(-q)
|
||
function cpnovcs() {
|
||
local src="$1" destdir="$2"
|
||
[ -d "$destdir" ] || mkdir -p "$destdir" || return 1
|
||
if progexists rsync; then
|
||
local gitexclude=/.git/
|
||
if [ "${src%/}" == "$src" ]; then
|
||
gitexclude="/$(basename -- "$src")$gitexclude"
|
||
fi
|
||
rsync -a ${__CPNOVCS_RSYNC_SLOW:+-c} --exclude CVS/ --exclude .svn/ --exclude "$gitexclude" "${__CPNOVCS_RSYNC_ARGS[@]}" "$src" "$destdir/"
|
||
elif [ "${src%/}" != "$src" ]; then
|
||
__cpdir "$src" "$destdir"
|
||
else
|
||
local srcname="$(basename -- "$src")"
|
||
mkdir -p "$destdir/$srcname"
|
||
__cpdir "$src" "$destdir/$srcname"
|
||
fi
|
||
}
|
||
function cpdirnovcs() {
|
||
if [ -d "$1" ]; then
|
||
cpnovcs "$1/" "$2"
|
||
else
|
||
cpnovcs "$1" "$2"
|
||
fi
|
||
}
|
||
function doinplace() {
|
||
if [ -n "$1" -a "$1" != "-" ]; then
|
||
local __dip_file="$1"; shift
|
||
autoclean "$__dip_file.tmp.$$"
|
||
"$@" <"$__dip_file" >"$__dip_file.tmp.$$"
|
||
local s=$?
|
||
[ "$s" == 0 ] && /bin/cat "$__dip_file.tmp.$$" >"$__dip_file"
|
||
/bin/rm -f "$__dip_file.tmp.$$"
|
||
return $s
|
||
else
|
||
shift
|
||
"$@"
|
||
fi
|
||
}
|
||
function doinplacef() {
|
||
if [ -n "$1" -a "$1" != "-" ]; then
|
||
local __dip_file="$1"; shift
|
||
autoclean "$__dip_file.tmp.$$"
|
||
"$@" <"$__dip_file" >"$__dip_file.tmp.$$"
|
||
local s=$?
|
||
/bin/cat "$__dip_file.tmp.$$" >"$__dip_file"
|
||
/bin/rm -f "$__dip_file.tmp.$$"
|
||
return $s
|
||
else
|
||
shift
|
||
"$@"
|
||
fi
|
||
}
|
||
function stripnl() {
|
||
tr -d '\r\n'
|
||
}
|
||
function _nl2lf() {
|
||
awk 'BEGIN {RS="\r|\r\n|\n"} {print}'
|
||
}
|
||
function nl2lf() {
|
||
doinplace "$1" _nl2lf
|
||
}
|
||
function _nl2crlf() {
|
||
awk 'BEGIN {RS="\r|\r\n|\n"} {print $0 "\r"}'
|
||
}
|
||
function nl2crlf() {
|
||
doinplace "$1" _nl2crlf
|
||
}
|
||
function _nl2cr() {
|
||
awk 'BEGIN {RS="\r|\r\n|\n"; ORS=""} {print $0 "\r"}'
|
||
}
|
||
function nl2cr() {
|
||
doinplace "$1" _nl2cr
|
||
}
|
||
function _latin1compat() {
|
||
LANG=fr_FR.UTF-8 sed $'
|
||
s/[’]/\x27/g
|
||
s/[«»]/"/g
|
||
s/[\xC2\xA0\xE2\x80\x87\xE2\x80\xAF\xE2\x81\xA0]/ /g
|
||
'
|
||
}
|
||
function _noaccents() {
|
||
LANG=fr_FR.UTF-8 sed '
|
||
s/[à]/a/g
|
||
s/[éèêë]/e/g
|
||
s/[ïî]/i/g
|
||
s/[ôö]/o/g
|
||
s/[üû]/u/g
|
||
s/[ç]/c/g
|
||
s/[À]/A/g
|
||
s/[ÉÈÊË]/E/g
|
||
s/[ÏÎ]/I/g
|
||
s/[ÔÖ]/O/g
|
||
s/[ÜÛ]/U/g
|
||
s/[Ç]/C/g
|
||
'
|
||
}
|
||
function list_all() {
|
||
local curdir="$(pwd)"
|
||
local b="${1:-.}"; shift
|
||
|
||
cd "$b" 2>/dev/null || return
|
||
eval "$(__la_cmd "$@")" | while read f; do
|
||
[ "$f" == "." -o "$f" == ".." ] && continue
|
||
rawecho "$f"
|
||
done
|
||
cd "$curdir"
|
||
}
|
||
function __la_cmd() {
|
||
[ -n "$*" ] || set '*'
|
||
local arg
|
||
local cmd="/bin/ls -1d"
|
||
for arg in "$@"; do
|
||
cmd="$cmd $(quote_arg "$arg")"
|
||
done
|
||
cmd="$cmd 2>/dev/null"
|
||
echo "$cmd"
|
||
}
|
||
function list_files() {
|
||
local f
|
||
local curdir="$(pwd)"
|
||
local b="${1:-.}"; shift
|
||
|
||
cd "$b" 2>/dev/null || return
|
||
eval "$(__la_cmd "$@")" | while read f; do
|
||
[ -f "$f" ] && rawecho "$f"
|
||
done
|
||
cd "$curdir"
|
||
}
|
||
function list_dirs() {
|
||
local f
|
||
local curdir="$(pwd)"
|
||
local b="${1:-.}"; shift
|
||
|
||
cd "$b" 2>/dev/null || return
|
||
eval "$(__la_cmd "$@")" | while read f; do
|
||
[ "$f" == "." -o "$f" == ".." ] && continue
|
||
[ -d "$f" ] && rawecho "$f"
|
||
done
|
||
cd "$curdir"
|
||
}
|
||
function __array_ls() {
|
||
local __al_l="list_${1:-all}"; shift
|
||
local __al_an="$1"; shift
|
||
local __al_d="${1:-.}"; shift
|
||
local -a __al_fs
|
||
array_from_lines __al_fs "$("$__al_l" "$__al_d" "$@")"
|
||
local __al_f
|
||
array_new "$__al_an"
|
||
for __al_f in "${__al_fs[@]}"; do
|
||
array_add "$__al_an" "$__al_d/$__al_f"
|
||
done
|
||
}
|
||
function array_lsall() {
|
||
__array_ls all "$@"
|
||
}
|
||
function array_lsdirs() {
|
||
__array_ls dirs "$@"
|
||
}
|
||
function array_lsfiles() {
|
||
__array_ls files "$@"
|
||
}
|
||
function filter_empty() {
|
||
sed '/^$/d'
|
||
}
|
||
function filter_vcspath() {
|
||
sed '
|
||
/^.git$/d
|
||
/^.git\//d
|
||
/\/.git$/d
|
||
/\/.git\//d
|
||
/^.svn$/d
|
||
/^.svn\//d
|
||
/\/.svn$/d
|
||
/\/.svn\//d
|
||
'
|
||
}
|
||
function merge_contlines() {
|
||
awk 'substr($0, length($0)) == "\\" {
|
||
while (getline nextline) {
|
||
$0 = substr($0, 1, length($0) - 1) nextline
|
||
if (substr($0, length($0)) != "\\") break
|
||
}
|
||
print
|
||
next
|
||
}
|
||
{print}'
|
||
}
|
||
function filter_comment() {
|
||
local -a merge
|
||
[ "$1" == -m ] && merge=(merge_contlines) || merge=(cat)
|
||
awk '
|
||
/^[ \t]*#/ { next }
|
||
/^[ \t]*$/ { next }
|
||
{ print }' | "${merge[@]}"
|
||
}
|
||
function filter_conf() {
|
||
local -a merge
|
||
[ "$1" == -m ] && merge=(merge_contlines) || merge=(cat)
|
||
grep -v '^#' | grep -v '^$' | "${merge[@]}"
|
||
}
|
||
function is_archive() {
|
||
local name="${1%.zip}"
|
||
name="${name%.tgz}"
|
||
name="${name%.tbz2}"
|
||
name="${name%.tar.gz}"
|
||
name="${name%.tar.bz2}"
|
||
name="${name%.tar}"
|
||
name="${name%.jar}"
|
||
name="${name%.war}"
|
||
name="${name%.ear}"
|
||
[ "$name" != "$1" ]
|
||
}
|
||
function extract_archive() {
|
||
local arch="$1" destdir="${2:-.}"
|
||
shift; shift
|
||
if endswith "$arch" .zip; then
|
||
unzip -q -d "$destdir" "$arch" "$@" || return
|
||
elif endswith "$arch" .tgz || endswith "$arch" .tar.gz; then
|
||
tar xzf "$arch" -C "$destdir" "$@" || return
|
||
elif endswith "$arch" .tbz2 || endswith "$arch" .tar.bz2; then
|
||
tar xjf "$arch" -C "$destdir" "$@" || return
|
||
elif endswith "$arch" .tar; then
|
||
tar xf "$arch" -C "$destdir" "$@" || return
|
||
elif endswith "$arch" .jar || endswith "$arch" .war || endswith "$arch" .ear; then
|
||
(
|
||
arch="$(abspath "$arch")"
|
||
cd "$destdir"
|
||
jar xf "$arch" "$@"
|
||
) || return
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
function get_archive_basename() {
|
||
local basename="$(basename -- "$1")"
|
||
basename="${basename%.zip}"
|
||
basename="${basename%.tgz}"
|
||
basename="${basename%.tbz2}"
|
||
basename="${basename%.gz}"
|
||
basename="${basename%.bz2}"
|
||
basename="${basename%.tar}"
|
||
basename="${basename%.jar}"
|
||
basename="${basename%.war}"
|
||
basename="${basename%.ear}"
|
||
echo "$basename"
|
||
}
|
||
function get_archive_appname() {
|
||
local appname="$(basename -- "$1")"
|
||
appname="${appname%.zip}"
|
||
appname="${appname%.tgz}"
|
||
appname="${appname%.tbz2}"
|
||
appname="${appname%.gz}"
|
||
appname="${appname%.bz2}"
|
||
appname="${appname%.tar}"
|
||
appname="${appname%.jar}"
|
||
appname="${appname%.war}"
|
||
appname="${appname%.ear}"
|
||
echo "$appname" | awk '{
|
||
if (match($0, /[-_.]([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/)) {
|
||
print substr($0, 1, RSTART - 1)
|
||
} else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/)) {
|
||
print substr($0, 1, RSTART - 1)
|
||
} else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) {
|
||
print substr($0, 1, RSTART - 1)
|
||
} else {
|
||
print $0
|
||
}
|
||
}'
|
||
}
|
||
function get_archive_versionsuffix() {
|
||
local basename="$(get_archive_basename "$1")"
|
||
echo "$basename" | awk '{
|
||
if (match($0, /([-_.][0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) {
|
||
print vs["1"]
|
||
} else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) {
|
||
print vs["1"]
|
||
} else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) {
|
||
print vs["1"]
|
||
}
|
||
}'
|
||
}
|
||
function get_archive_version() {
|
||
local basename="$(get_archive_basename "$1")"
|
||
echo "$basename" | awk '{
|
||
if (match($0, /[-_.]([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) {
|
||
print vs["1"]
|
||
} else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) {
|
||
print vs["1"]
|
||
} else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) {
|
||
print vs["1"]
|
||
}
|
||
}'
|
||
}
|
||
function __dump_usernames() {
|
||
</etc/passwd awkrun FS=: '($3 + 0) >= 500 && $6 ~ /^\/home\// { print $1 }'
|
||
}
|
||
function dump_usernames() {
|
||
array_from_lines "${1:-usernames}" "$(__dump_usernames)"
|
||
}
|
||
function __resolv_ips() {
|
||
LANG=C host "$1" 2>/dev/null | awk '/address / { gsub(/^.*address /, ""); print }'
|
||
}
|
||
function resolv_ips() {
|
||
array_from_lines "${1:-ips}" "$(__resolv_ips "$2")"
|
||
}
|
||
function __resolv_hosts() {
|
||
LANG=C host "$1" 2>/dev/null | awk '/domain name pointer / { gsub(/^.*domain name pointer /, ""); gsub(/\.$/, ""); print }'
|
||
}
|
||
function resolv_hosts() {
|
||
array_from_lines "${1:-hosts}" "$(__resolv_hosts "$2")"
|
||
}
|
||
function runscript_as() {
|
||
local OENC="$UTF8"
|
||
local user="${1:-root}"; shift
|
||
local exec_maybe=
|
||
if [ "$1" = "exec" ]; then
|
||
exec_maybe=exec
|
||
shift
|
||
fi
|
||
|
||
local cmd
|
||
cmd="\
|
||
__estack=$(quoted_arg "$__estack")
|
||
__tlevel=$(quoted_args "$__tlevel")
|
||
export __estack __tlevel
|
||
exec ${BASH:-/bin/sh} $(quoted_args "$@")"
|
||
|
||
if is_yes "$UTOOLS_USES_SU" || ! progexists sudo; then
|
||
eecho "Entrez le mot de passe de root"
|
||
$exec_maybe su "$user" -c "$cmd"
|
||
else
|
||
if [ "$user" == "root" ]; then
|
||
$exec_maybe sudo -p "Entrez le mot de passe de %u: " "${BASH:-/bin/sh}" -c "$cmd"
|
||
else
|
||
$exec_maybe sudo -p "Entrez le mot de passe de %u: " su "$user" -c "$cmd"
|
||
fi
|
||
fi
|
||
}
|
||
function runscript_as_root() {
|
||
if is_root; then
|
||
local exec_maybe=
|
||
if [ "$1" = "exec" ]; then
|
||
exec_maybe=exec
|
||
shift
|
||
fi
|
||
$exec_maybe "${BASH:-/bin/sh}" "$@"
|
||
else
|
||
runscript_as root "$@"
|
||
fi
|
||
}
|
||
function run_as() {
|
||
local user="${1:-root}"; shift
|
||
local exec_maybe=exec
|
||
if [ "$1" = "--noexec" ]; then
|
||
exec_maybe=
|
||
shift
|
||
fi
|
||
|
||
runscript_as "$user" $exec_maybe "$0" "$@"
|
||
}
|
||
function run_as_root() {
|
||
is_root || run_as root "$@"
|
||
}
|
||
function check_user() {
|
||
local user
|
||
for user in "$@"; do
|
||
[ "$USER" == "$user" ] && return 0
|
||
done
|
||
return 1
|
||
}
|
||
function ensure_user() {
|
||
local -a users
|
||
while [ $# -gt 0 -a "$1" != "--" ]; do
|
||
array_add users "$1"
|
||
shift
|
||
done
|
||
[ "$1" == "--" ] && shift
|
||
|
||
if ! check_user "${users[@]}"; then
|
||
if [ ${#users[*]} -gt 1 ]; then
|
||
ewarn "Cette commande doit être lancée avec l'un des users ${users[*]}"
|
||
else
|
||
ewarn "Cette commande doit être lancée avec le user ${users[0]}"
|
||
fi
|
||
if ask_yesno "Voulez-vous tenter de relancer la commande avec le bon user?" O; then
|
||
estep "Lancement du script avec le user ${users[0]}"
|
||
run_as "${users[0]}" "$@"
|
||
return 1
|
||
elif is_root; then
|
||
return 11
|
||
else
|
||
return 10
|
||
fi
|
||
fi
|
||
return 0
|
||
}
|
||
function check_hostname() {
|
||
local userhost user host path
|
||
for userhost in "$@"; do
|
||
splitfsep "$userhost" : userhost path
|
||
splituserhost "$userhost" user host
|
||
[ "$MYHOSTNAME" == "${host%%.*}" ] && return 0
|
||
done
|
||
return 1
|
||
}
|
||
function check_userhostname() {
|
||
local userhost path user host
|
||
for userhost in "$@"; do
|
||
if check_hostname "$userhost"; then
|
||
[[ "$userhost" == *@* ]] || return 0
|
||
splitfsep "$userhost" : userhost path
|
||
splituserhost "$userhost" user host
|
||
check_user "$user" && return 0
|
||
fi
|
||
done
|
||
return 1
|
||
}
|
||
UTOOLS_ENSURE_HOSTNAME_SSH_OPTS=()
|
||
function ensure_hostname() {
|
||
local -a userhosts
|
||
while [ $# -gt 0 -a "$1" != "--" ]; do
|
||
array_add userhosts "$1"
|
||
shift
|
||
done
|
||
[ "$1" == "--" ] && shift
|
||
|
||
local userhost user host path
|
||
if ! check_hostname "${userhosts[@]}"; then
|
||
if [ ${#userhosts[*]} -gt 1 ]; then
|
||
ewarn "Cette commande n'est valide que sur l'un des hôtes ${userhosts[*]}"
|
||
else
|
||
ewarn "Cette commande n'est valide que sur l'hôte ${userhosts[0]}"
|
||
fi
|
||
|
||
enote "Vous pouvez tenter de relancer le script sur ${userhosts[0]}, mais cela requière que ce script ET les données dont il a besoin soient installés dans la même version et dans le même répertoire sur l'hôte distant"
|
||
if ask_yesno "Voulez-vous tenter de relancer le script sur l'hôte distant?" N; then
|
||
splitfsep "${userhosts[0]}" : userhost path
|
||
splituserhost "$userhost" user host
|
||
[ -n "$user" ] || user=root
|
||
|
||
estep "Lancement de la commande sur l'hôte distant $user@$host"
|
||
local cmd
|
||
[ -n "$path" ] && cmd="$(quoted_args cd "$path"); "
|
||
cmd="$cmd$(quoted_args "$script" "$@")"
|
||
ssh -qt "${UTOOLS_ENSURE_HOSTNAME_SSH_OPTS[@]}" "$user@$host" "$cmd"
|
||
[ $? -eq 255 ] && return 12
|
||
return 1
|
||
else
|
||
return 11
|
||
fi
|
||
fi
|
||
local userhost user host
|
||
for userhost in "${userhosts[@]}"; do
|
||
[[ "$userhost" == *@* ]] || continue
|
||
if check_hostname "$userhost"; then
|
||
splitfsep "$userhost" : userhost path
|
||
splituserhost "$userhost" user host
|
||
[ -n "$path" ] && cd "$path"
|
||
ensure_user "$user" -- "$@"
|
||
return $?
|
||
fi
|
||
done
|
||
return 0
|
||
}
|
||
|
||
__AWKDEF_FUNCTIONS='
|
||
function quote_html(s) {
|
||
gsub(/&/, "\\&", s)
|
||
gsub(/"/, "\\"", s)
|
||
gsub(/>/, "\\>", s)
|
||
gsub(/</, "\\<", s)
|
||
return s
|
||
}
|
||
function unquote_html(s) {
|
||
gsub(/</, "<", s)
|
||
gsub(/>/, ">", s)
|
||
gsub(/"/, "\"", s)
|
||
gsub(/&/, "\\&", s)
|
||
return s
|
||
}
|
||
function quote_value(s) {'"
|
||
gsub(/'/, \"'\\\\''\", s)
|
||
return \"'\" s \"'\"
|
||
"'}
|
||
function quoted_values( i, line) {
|
||
line = ""
|
||
for (i = 1; i <= NF; i++) {
|
||
if (i > 1) line = line " "
|
||
line = line quote_value($i)
|
||
}
|
||
return line
|
||
}
|
||
function quote_subrepl(s) {
|
||
gsub(/\\/, "\\\\", s)
|
||
gsub(/&/, "\\\\&", s)
|
||
return s
|
||
}
|
||
function quote_grep(s) {
|
||
gsub(/[[\\.^$*]/, "\\\\&", s)
|
||
return s
|
||
}
|
||
function quote_egrep(s) {
|
||
gsub(/[[\\.^$*+?()|{]/, "\\\\&", s)
|
||
return s
|
||
}
|
||
function quote_sql(s) {'"
|
||
gsub(/'/, \"''\", s)
|
||
return \"'\" s \"'\"
|
||
"'}
|
||
function unquote_mysqlcsv(s) {
|
||
gsub(/\\n/, "\n", s)
|
||
gsub(/\\t/, "\t", s)
|
||
gsub(/\\0/, "\0", s)
|
||
gsub(/\\\\/, "\\", s)
|
||
return s
|
||
}
|
||
function array_new(dest) {
|
||
dest[0] = 0 # forcer awk à considérer dest comme un tableau
|
||
delete dest
|
||
}
|
||
function array_newsize(dest, size, i) {
|
||
dest[0] = 0 # forcer awk à considérer dest comme un tableau
|
||
delete dest
|
||
size = int(size)
|
||
for (i = 1; i <= size; i++) {
|
||
dest[i] = ""
|
||
}
|
||
}
|
||
function array_len(values, count, i) {
|
||
count = 0
|
||
for (i in values) {
|
||
count++
|
||
}
|
||
return count
|
||
}
|
||
function mkindices(values, indices, i, j) {
|
||
array_new(indices)
|
||
j = 1
|
||
for (i in values) {
|
||
indices[j++] = int(i)
|
||
}
|
||
return asort(indices)
|
||
}
|
||
function array_copy(dest, src, count, indices, i) {
|
||
array_new(dest)
|
||
count = mkindices(src, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
dest[indices[i]] = src[indices[i]]
|
||
}
|
||
}
|
||
function array_getlastindex(src, count, indices) {
|
||
count = mkindices(src, indices)
|
||
if (count == 0) return 0
|
||
return indices[count]
|
||
}
|
||
function array_add(dest, value, lastindex) {
|
||
lastindex = array_getlastindex(dest)
|
||
dest[lastindex + 1] = value
|
||
}
|
||
function array_deli(dest, i, l) {
|
||
i = int(i)
|
||
if (i == 0) return
|
||
l = array_len(dest)
|
||
while (i < l) {
|
||
dest[i] = dest[i + 1]
|
||
i++
|
||
}
|
||
delete dest[l]
|
||
}
|
||
function array_del(dest, value, ignoreCase, i) {
|
||
do {
|
||
i = key_index(value, dest, ignoreCase)
|
||
if (i != 0) array_deli(dest, i)
|
||
} while (i != 0)
|
||
}
|
||
function array_extend(dest, src, count, lastindex, indices, i) {
|
||
lastindex = array_getlastindex(dest)
|
||
count = mkindices(src, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
dest[lastindex + i] = src[indices[i]]
|
||
}
|
||
}
|
||
function array_fill(dest, i) {
|
||
array_new(dest)
|
||
for (i = 1; i <= NF; i++) {
|
||
dest[i] = $i
|
||
}
|
||
}
|
||
function array_getline(src, count, indices, i, j) {
|
||
$0 = ""
|
||
count = mkindices(src, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
j = indices[i]
|
||
$j = src[j]
|
||
}
|
||
}
|
||
function array_appendline(src, count, indices, i, nf, j) {
|
||
count = mkindices(src, indices)
|
||
nf = NF
|
||
for (i = 1; i <= count; i++) {
|
||
j = nf + indices[i]
|
||
$j = src[indices[i]]
|
||
}
|
||
}
|
||
function in_array(value, values, ignoreCase, i) {
|
||
if (ignoreCase) {
|
||
value = tolower(value)
|
||
for (i in values) {
|
||
if (tolower(values[i]) == value) return 1
|
||
}
|
||
} else {
|
||
for (i in values) {
|
||
if (values[i] == value) return 1
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
function key_index(value, values, ignoreCase, i) {
|
||
if (ignoreCase) {
|
||
value = tolower(value)
|
||
for (i in values) {
|
||
if (tolower(values[i]) == value) return int(i)
|
||
}
|
||
} else {
|
||
for (i in values) {
|
||
if (values[i] == value) return int(i)
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
function array2s(values, prefix, sep, suffix, noindices, first, i, s) {
|
||
if (!prefix) prefix = "["
|
||
if (!sep) sep = ", "
|
||
if (!suffix) suffix = "]"
|
||
s = prefix
|
||
first = 1
|
||
for (i in values) {
|
||
if (first) first = 0
|
||
else s = s sep
|
||
if (!noindices) s = s "[" i "]="
|
||
s = s values[i]
|
||
}
|
||
s = s suffix
|
||
return s
|
||
}
|
||
function array2so(values, prefix, sep, suffix, noindices, count, indices, i, s) {
|
||
if (!prefix) prefix = "["
|
||
if (!sep) sep = ", "
|
||
if (!suffix) suffix = "]"
|
||
s = prefix
|
||
count = mkindices(values, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
if (i > 1) s = s sep
|
||
if (!noindices) s = s "[" indices[i] "]="
|
||
s = s values[indices[i]]
|
||
}
|
||
s = s suffix
|
||
return s
|
||
}
|
||
function array_join(values, sep, prefix, suffix, count, indices, i, s) {
|
||
s = prefix
|
||
count = mkindices(values, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
if (i > 1) s = s sep
|
||
s = s values[indices[i]]
|
||
}
|
||
s = s suffix
|
||
return s
|
||
}
|
||
function printto(s, output) {
|
||
if (output == "") {
|
||
print s
|
||
} else if (output ~ /^>>/) {
|
||
sub(/^>>/, "", output)
|
||
print s >>output
|
||
} else if (output ~ /^>/) {
|
||
sub(/^>/, "", output)
|
||
print s >output
|
||
} else {
|
||
print s >output
|
||
}
|
||
}
|
||
function find_line(input, field, value, orig, line) {
|
||
orig = $0
|
||
line = ""
|
||
while ((getline <input) > 0) {
|
||
if ($field == value) {
|
||
line = $0
|
||
break
|
||
}
|
||
}
|
||
close(input)
|
||
$0 = orig
|
||
return line
|
||
}
|
||
function merge_line(input, field, key, line) {
|
||
line = find_line(input, field, $key)
|
||
if (line != "") $0 = $0 FS line
|
||
}
|
||
function __csv_parse_quoted(line, destl, colsep, qchar, echar, pos, tmpl, nextc, resl) {
|
||
line = substr(line, 2)
|
||
resl = ""
|
||
while (1) {
|
||
pos = index(line, qchar)
|
||
if (pos == 0) {
|
||
resl = resl line
|
||
destl[0] = ""
|
||
destl[1] = 0
|
||
return resl
|
||
}
|
||
if (echar != "" && pos > 1) {
|
||
prevc = substr(line, pos - 1, 1)
|
||
quotec = substr(line, pos, 1)
|
||
nextc = substr(line, pos + 1, 1)
|
||
if (prevc == echar) {
|
||
tmpl = substr(line, 1, pos - 2)
|
||
resl = resl tmpl quotec
|
||
line = substr(line, pos + 1)
|
||
continue
|
||
}
|
||
tmpl = substr(line, 1, pos - 1)
|
||
if (nextc == colsep || nextc == "") {
|
||
resl = resl tmpl
|
||
destl[0] = substr(line, pos + 2)
|
||
destl[1] = nextc == colsep
|
||
return resl
|
||
} else {
|
||
resl = resl tmpl quotec
|
||
line = substr(line, pos + 1)
|
||
}
|
||
} else {
|
||
tmpl = substr(line, 1, pos - 1)
|
||
quotec = substr(line, pos, 1)
|
||
nextc = substr(line, pos + 1, 1)
|
||
if (nextc == colsep || nextc == "") {
|
||
resl = resl tmpl
|
||
destl[0] = substr(line, pos + 2)
|
||
destl[1] = nextc == colsep
|
||
return resl
|
||
} else if (nextc == qchar) {
|
||
resl = resl tmpl quotec
|
||
line = substr(line, pos + 2)
|
||
} else {
|
||
resl = resl tmpl quotec
|
||
line = substr(line, pos + 1)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
function __csv_parse_unquoted(line, destl, colsep, qchar, echar, pos) {
|
||
pos = index(line, colsep)
|
||
if (pos == 0) {
|
||
destl[0] = ""
|
||
destl[1] = 0
|
||
return line
|
||
} else {
|
||
destl[0] = substr(line, pos + 1)
|
||
destl[1] = 1
|
||
return substr(line, 1, pos - 1)
|
||
}
|
||
}
|
||
function __array_parsecsv(fields, line, nbfields, colsep, qchar, echar, shouldparse, destl, i) {
|
||
array_new(fields)
|
||
array_new(destl)
|
||
i = 1
|
||
shouldparse = 0
|
||
while (shouldparse || line != "") {
|
||
if (index(line, qchar) == 1) {
|
||
value = __csv_parse_quoted(line, destl, colsep, qchar, echar)
|
||
line = destl[0]
|
||
shouldparse = destl[1]
|
||
} else {
|
||
value = __csv_parse_unquoted(line, destl, colsep, qchar, echar)
|
||
line = destl[0]
|
||
shouldparse = destl[1]
|
||
}
|
||
fields[i] = value
|
||
i = i + 1
|
||
}
|
||
if (nbfields) {
|
||
nbfields = int(nbfields)
|
||
i = array_len(fields)
|
||
while (i < nbfields) {
|
||
i++
|
||
fields[i] = ""
|
||
}
|
||
}
|
||
return array_len(fields)
|
||
}
|
||
BEGIN {
|
||
DEFAULT_COLSEP = ","
|
||
DEFAULT_QCHAR = "\""
|
||
DEFAULT_ECHAR = ""
|
||
}
|
||
function array_parsecsv2(fields, line, nbfields, colsep, qchar, echar) {
|
||
return __array_parsecsv(fields, line, nbfields, colsep, qchar, echar)
|
||
}
|
||
function array_parsecsv(fields, line, nbfields, colsep, qchar, echar) {
|
||
if (colsep == "") colsep = DEFAULT_COLSEP
|
||
if (qchar == "") qchar = DEFAULT_QCHAR
|
||
if (echar == "") echar = DEFAULT_ECHAR
|
||
return __array_parsecsv(fields, line, nbfields, colsep, qchar, echar)
|
||
}
|
||
function parsecsv(line, fields) {
|
||
array_parsecsv(fields, line)
|
||
array_getline(fields)
|
||
return NF
|
||
}
|
||
function getlinecsv(file, fields) {
|
||
if (file) {
|
||
getline <file
|
||
} else {
|
||
getline
|
||
}
|
||
return parsecsv($0)
|
||
}
|
||
function __csv_should_quote(s) {
|
||
if (s ~ /^[[:blank:][:cntrl:][:space:]]/) return 1
|
||
if (s ~ /[[:blank:][:cntrl:][:space:]]$/) return 1
|
||
return 0
|
||
}
|
||
function array_formatcsv2(fields, colsep, mvsep, qchar, echar, count, indices, line, i, value) {
|
||
line = ""
|
||
count = mkindices(fields, indices)
|
||
for (i = 1; i <= count; i++) {
|
||
value = fields[indices[i]]
|
||
if (i > 1) line = line colsep
|
||
if (qchar != "" && index(value, qchar) != 0) {
|
||
if (echar != "") gsub(qchar, quote_subrepl(echar) "&", value);
|
||
else gsub(qchar, "&&", value);
|
||
}
|
||
if (qchar != "" && (index(value, mvsep) != 0 || index(value, colsep) != 0 || index(value, qchar) != 0 || __csv_should_quote(value))) {
|
||
line = line qchar value qchar
|
||
} else {
|
||
line = line value
|
||
}
|
||
}
|
||
return line
|
||
}
|
||
function array_formatcsv(fields) {
|
||
return array_formatcsv2(fields, ",", ";", "\"", "")
|
||
}
|
||
function array_printcsv(fields, output) {
|
||
printto(array_formatcsv(fields), output)
|
||
}
|
||
function get_formatcsv( fields) {
|
||
array_fill(fields)
|
||
return array_formatcsv(fields)
|
||
}
|
||
function formatcsv() {
|
||
$0 = get_formatcsv()
|
||
}
|
||
function printcsv(output, fields) {
|
||
array_fill(fields)
|
||
array_printcsv(fields, output)
|
||
}
|
||
function array_findcsv(fields, input, field, value, nbfields, orig, found, i) {
|
||
array_new(orig)
|
||
array_fill(orig)
|
||
array_new(fields)
|
||
found = 0
|
||
while ((getline <input) > 0) {
|
||
array_parsecsv(fields, $0, nbfields)
|
||
if (fields[field] == value) {
|
||
found = 1
|
||
break
|
||
}
|
||
}
|
||
close(input)
|
||
array_getline(orig)
|
||
if (!found) {
|
||
delete fields
|
||
if (nbfields) {
|
||
nbfields = int(nbfields)
|
||
i = array_len(fields)
|
||
while (i < nbfields) {
|
||
i++
|
||
fields[i] = ""
|
||
}
|
||
}
|
||
}
|
||
return found
|
||
}
|
||
|
||
function __and(var, x, l_res, l_i) {
|
||
l_res=0;
|
||
for (l_i=0; l_i < 8; l_i++){
|
||
if (var%2 == 1 && x%2 == 1) l_res=l_res/2 + 128;
|
||
else l_res/=2;
|
||
var=int(var/2);
|
||
x=int(x/2);
|
||
}
|
||
return l_res;
|
||
}
|
||
function __lshift(var, x) {
|
||
while(x > 0){
|
||
var*=2;
|
||
x--;
|
||
}
|
||
return var;
|
||
}
|
||
function __rshift(var, x) {
|
||
while(x > 0){
|
||
var=int(var/2);
|
||
x--;
|
||
}
|
||
return var;
|
||
}
|
||
BEGIN {
|
||
__BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||
}
|
||
function b64decode(src, result, base1, base2, base3, base4) {
|
||
result = ""
|
||
while (length(src) > 0) {
|
||
base1 = substr(src, 1, 1)
|
||
base2 = substr(src, 2, 1)
|
||
base3 = substr(src, 3, 1); if (base3 == "") base3 = "="
|
||
base4 = substr(src, 4, 1); if (base4 == "") base4 = "="
|
||
byte1 = index(__BASE64, base1) - 1
|
||
if (byte1 < 0) byte1 = 0
|
||
byte2 = index(__BASE64, base2) - 1
|
||
if (byte2 < 0) byte2 = 0
|
||
byte3 = index(__BASE64, base3) - 1
|
||
if (byte3 < 0) byte3 = 0
|
||
byte4 = index(__BASE64, base4) - 1
|
||
if (byte4 < 0) byte4 = 0
|
||
result = result sprintf( "%c", __lshift(__and(byte1, 63), 2) + __rshift(__and(byte2, 48), 4) )
|
||
if (base3 != "=") result = result sprintf( "%c", __lshift(__and(byte2, 15), 4) + __rshift(__and(byte3, 60), 2) )
|
||
if (base4 != "=") result = result sprintf( "%c", __lshift(__and(byte3, 3), 6) + byte4 )
|
||
src = substr(src, 5)
|
||
}
|
||
return result
|
||
}
|
||
'
|
||
function awkdef() {
|
||
|
||
if [ "${1:0:3}" == "-f" ]; then
|
||
shift
|
||
echo "$__AWKDEF_FUNCTIONS"
|
||
fi
|
||
if [ $# -gt 0 ]; then
|
||
local __ad_arg __ad_vpos __ad_name __ad_value
|
||
echo "BEGIN {"
|
||
while [ -n "${1:0:1}" ]; do
|
||
__ad_arg="${1:0:256}"
|
||
local __ad_array=
|
||
if [ "${__ad_arg%\[@\]}" != "$__ad_arg" ]; then
|
||
__ad_array=1
|
||
__ad_name="${__ad_arg%\[@\]}"
|
||
[ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break
|
||
__ad_value="$__ad_name"
|
||
elif [[ "$__ad_arg" == *\[@\]=* ]]; then
|
||
__ad_array=1
|
||
__ad_name="${__ad_arg%%\[@\]=*}"
|
||
[ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break
|
||
__ad_vpos=$((${#__ad_name} + 4))
|
||
__ad_value="${1:$__ad_vpos}"
|
||
[ ${#__ad_value} -ne 0 ] || __ad_value="$__ad_name"
|
||
elif [[ "$__ad_arg" == *=* ]]; then
|
||
local __ad_int= __ad_str=
|
||
__ad_name="${__ad_arg%%=*}"
|
||
__ad_vpos=$((${#__ad_name} + 1))
|
||
if [ "${__ad_name%:int}" != "$__ad_name" ]; then
|
||
__ad_int=1
|
||
__ad_name="${__ad_name%:int}"
|
||
elif [ "${__ad_name%:str}" != "$__ad_name" ]; then
|
||
__ad_str=1
|
||
__ad_name="${__ad_name%:str}"
|
||
fi
|
||
[ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break
|
||
__ad_value="${1:$__ad_vpos}"
|
||
if [ -n "$__ad_int" ]; then
|
||
echo "$__ad_name = int($(quoted_awk "$__ad_value") + 0)"
|
||
elif [ -n "$__ad_str" ]; then
|
||
echo "$__ad_name = $(quoted_awk "$__ad_value")"
|
||
elif [ ${#__ad_value} -lt 256 ] && isnum "$__ad_value"; then
|
||
echo "$__ad_name = $__ad_value"
|
||
else
|
||
echo "$__ad_name = $(quoted_awk "$__ad_value")"
|
||
fi
|
||
else
|
||
break
|
||
fi
|
||
if [ -n "$__ad_array" ]; then
|
||
if [ "${__ad_value:0:2}" == $'<\n' ]; then
|
||
local -a __ad_values
|
||
array_from_lines __ad_values "${__ad_value:2}"
|
||
__ad_value=__ad_values
|
||
fi
|
||
__ad_value="${__ad_value}[@]"
|
||
local __ad_i=1
|
||
echo "$__ad_name[0] = 0; delete $__ad_name"
|
||
for __ad_arg in "${!__ad_value}"; do
|
||
echo "$__ad_name[$__ad_i]=$(quoted_awk "$__ad_arg")"
|
||
__ad_i=$(($__ad_i + 1))
|
||
done
|
||
eval "echo \"\${__ad_name}_count = \${#$__ad_value}\""
|
||
fi
|
||
shift
|
||
done
|
||
echo "}"
|
||
for __ad_arg in "$@"; do
|
||
rawecho "$__ad_arg"
|
||
done
|
||
fi
|
||
}
|
||
function lawkrun() {
|
||
local -a __ar_defs __ar_args
|
||
while [ $# -gt 0 -a "$1" != "--" ]; do
|
||
__ar_defs=("${__ar_defs[@]}" "$1")
|
||
shift
|
||
done
|
||
shift
|
||
while [ $# -gt 0 ]; do
|
||
__ar_args=("${__ar_args[@]}" "$1")
|
||
shift
|
||
done
|
||
local __ar_script="$(awkdef "${__ar_defs[@]}")"
|
||
awk "$__ar_script" "${__ar_args[@]}"
|
||
}
|
||
function cawkrun() { LANG=C lawkrun "$@"; }
|
||
function awkrun() { LANG=C lawkrun "$@"; }
|
||
|
||
function __lf_get_age() {
|
||
local y=$(date "+%Y")
|
||
local dy=$(date "+%j"); while [ "${dy#0}" != "$dy" ]; do dy="${dy#0}"; done
|
||
[ -n "$dy" ] || dy=0
|
||
local h=$(date "+%H"); while [ "${h#0}" != "$h" ]; do h="${h#0}"; done
|
||
[ -n "$h" ] || h=0
|
||
echo $((($y * 365 + $dy) * 24 + $h))
|
||
}
|
||
function lf_trylock() {
|
||
local eoo lockfile max_hours=4
|
||
while [ -n "$1" ]; do
|
||
case "$1" in
|
||
-h) shift; max_hours="$1";;
|
||
--) shift; eoo=1;;
|
||
*) eoo=1;;
|
||
esac
|
||
[ -n "$eoo" ] && break
|
||
shift
|
||
done
|
||
|
||
lockfile="$1"
|
||
[ -n "$lockfile" ] || die "il faut spécifier un fichier pour le verrou"
|
||
|
||
local now="$(__lf_get_age)"
|
||
if (set -C; echo "$now" >"$lockfile") 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
local prev diff
|
||
if prev="$(<"$lockfile")"; then
|
||
diff="$(($now - $prev))"
|
||
if [ "$diff" -gt "$max_hours" ]; then
|
||
echo stale
|
||
else
|
||
echo locked
|
||
fi
|
||
elif [ -f "$lockfile" ]; then
|
||
echo retry
|
||
fi
|
||
return 1
|
||
}
|
||
function pidfile_set() {
|
||
local eoo pidfile pid=$$ replace=
|
||
while [ -n "$1" ]; do
|
||
case "$1" in
|
||
-p)
|
||
shift
|
||
pid="$1"
|
||
;;
|
||
-r)
|
||
replace=1
|
||
;;
|
||
--)
|
||
shift
|
||
eoo=1
|
||
;;
|
||
*)
|
||
eoo=1
|
||
;;
|
||
esac
|
||
[ -n "$eoo" ] && break
|
||
shift
|
||
done
|
||
|
||
pidfile="$1"
|
||
[ -n "$pidfile" ] || return 10
|
||
|
||
if [ -f "$pidfile" ]; then
|
||
local curpid="$(<"$pidfile")"
|
||
if is_running "$curpid"; then
|
||
return 1
|
||
elif [ -n "$replace" ]; then
|
||
/bin/rm -f "$pidfile" || return 10
|
||
else
|
||
return 2
|
||
fi
|
||
fi
|
||
|
||
echo_ "$pid" >"$pidfile" || return 10
|
||
autoclean "$pidfile"
|
||
return 0
|
||
}
|
||
function pidfile_check() {
|
||
local pidfile="$1"
|
||
[ -n "$pidfile" ] || return 10
|
||
|
||
if [ -f "$pidfile" ]; then
|
||
[ -r "$pidfile" ] || return 10
|
||
local pid="$(<"$pidfile")"
|
||
is_running "$pid" && return 0
|
||
fi
|
||
return 1
|
||
}
|
||
function page_maybe() {
|
||
if isatty; then
|
||
less -XF "$@"
|
||
else
|
||
cat
|
||
fi
|
||
}
|
||
|
||
|
||
function utools_local() {
|
||
local arg
|
||
[ -n "$*" ] || set -- opts verbosity interaction
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
parse_opts|opts|o|args) echo "local -a args";;
|
||
verbosity|v) echo "local __verbosity='$__verbosity'";;
|
||
interaction|i) echo "local __interaction='$__interaction'";;
|
||
esac
|
||
done
|
||
}
|
||
|
||
function isatty() {
|
||
tty -s <&1
|
||
}
|
||
function in_isatty() {
|
||
tty -s
|
||
}
|
||
function out_isatty() {
|
||
tty -s <&1
|
||
}
|
||
function err_isatty() {
|
||
tty -s <&2
|
||
}
|
||
function die() {
|
||
[ -n "$*" ] && eerror "$@"; exit 1
|
||
}
|
||
function exit_with {
|
||
[ -n "$*" ] && "$@"; exit $?
|
||
}
|
||
function die_with {
|
||
[ -n "$1" ] && eerror "$1"; shift; [ -n "$*" ] && "$@"; exit 1
|
||
}
|
||
|
||
TAB=$'\t'
|
||
LATIN1=iso-8859-1
|
||
LATIN9=iso-8859-15
|
||
UTF8=utf-8
|
||
OENC="$UTF8"
|
||
|
||
if ! progexists iconv; then
|
||
function iconv() { cat; }
|
||
fi
|
||
|
||
function __lang_encoding() {
|
||
local lang="$(<<<"$LANG" awk '{ print tolower($0) }')"
|
||
case "$lang" in
|
||
*@euro) echo "iso-8859-15";;
|
||
*.utf-8|*.utf8) echo "utf-8";;
|
||
*) echo "iso-8859-1";;
|
||
esac
|
||
}
|
||
function __norm_encoding() {
|
||
awk '{
|
||
enc = tolower($0)
|
||
gsub(/^latin$/, "latin1", enc)
|
||
gsub(/^latin1$/, "iso-8859-1", enc)
|
||
gsub(/^latin9$/, "iso-8859-15", enc)
|
||
gsub(/[-_]/, "", enc)
|
||
if (enc == "iso8859" || enc == "iso88591" || enc == "8859" || enc == "88591") print "iso-8859-1"
|
||
else if (enc == "iso885915" || enc == "885915") print "iso-8859-15"
|
||
else if (enc == "utf" || enc == "utf8") print "utf-8"
|
||
else print $0
|
||
}' <<<"$1"
|
||
}
|
||
function __init_encoding() {
|
||
local DEFAULT_ENCODING="$(__lang_encoding)"
|
||
[ -n "$DEFAULT_ENCODING" ] || DEFAULT_ENCODING=utf-8
|
||
[ -n "$UTOOLS_OUTPUT_ENCODING" ] || UTOOLS_OUTPUT_ENCODING="$DEFAULT_ENCODING"
|
||
UTOOLS_OUTPUT_ENCODING="$(__norm_encoding "$UTOOLS_OUTPUT_ENCODING")"
|
||
[ -n "$UTOOLS_INPUT_ENCODING" ] || UTOOLS_INPUT_ENCODING="$UTOOLS_OUTPUT_ENCODING"
|
||
UTOOLS_INPUT_ENCODING="$(__norm_encoding "$UTOOLS_INPUT_ENCODING")"
|
||
[ -n "$UTOOLS_EDITOR_ENCODING" ] || UTOOLS_EDITOR_ENCODING="$UTOOLS_INPUT_ENCODING"
|
||
UTOOLS_EDITOR_ENCODING="$(__norm_encoding "$UTOOLS_EDITOR_ENCODING")"
|
||
|
||
IENC="$UTOOLS_INPUT_ENCODING"
|
||
OENC="$UTOOLS_OUTPUT_ENCODING"
|
||
}
|
||
|
||
if [ -n "$UTOOLS_LANG" -a -z "$LANG" ]; then
|
||
export UTOOLS_LANG
|
||
export LANG="$UTOOLS_LANG"
|
||
fi
|
||
__init_encoding
|
||
|
||
function tooenc() {
|
||
local src="$1" from="${2:-$OENC}" to="${3:-$UTOOLS_OUTPUT_ENCODING}"
|
||
if [ "$from" == "$to" ]; then
|
||
rawecho "$src"
|
||
else
|
||
iconv -f "$from" -t "$to" <<<"$src"
|
||
fi
|
||
}
|
||
function uecho() {
|
||
tooenc "$*"
|
||
}
|
||
function tooenc_() {
|
||
local src="$1" from="${2:-$OENC}" to="${3:-$UTOOLS_OUTPUT_ENCODING}"
|
||
if [ "$from" == "$to" ]; then
|
||
rawecho_ "$src"
|
||
else
|
||
rawecho_ "$src" | iconv -f "$from" -t "$to"
|
||
fi
|
||
}
|
||
function uecho_() {
|
||
tooenc_ "$*"
|
||
}
|
||
function toienc() {
|
||
local __tie_var="$1" __tie_to="${2:-$IENC}" __tie_from="${3:-$UTOOLS_INPUT_ENCODING}"
|
||
if [ "$__tie_from" != "$__tie_to" ]; then
|
||
set_var "$__tie_var" "$(iconv -f "$__tie_from" -t "$__tie_to" <<<"${!__tie_var}")"
|
||
fi
|
||
}
|
||
function uread() {
|
||
[ -n "$*" ] || set -- REPLY
|
||
local __r_var
|
||
read "$@"
|
||
for __r_var in "$@"; do
|
||
[ -z "$__r_var" -o "${__r_var:0:1}" == "-" ] && continue # ignorer les options
|
||
toienc "$__r_var"
|
||
done
|
||
}
|
||
|
||
function stooenc() {
|
||
local from="${1:-$OENC}" to="${2:-$UTOOLS_OUTPUT_ENCODING}"
|
||
if [ "$from" == "$to" ]; then
|
||
cat
|
||
else
|
||
iconv -f "$from" -t "$to"
|
||
fi
|
||
}
|
||
function stoienc() {
|
||
local to="${1:-$IENC}" from="${2:-$UTOOLS_INPUT_ENCODING}"
|
||
if [ "$from" == "$to" ]; then
|
||
cat
|
||
else
|
||
iconv -f "$from" -t "$to"
|
||
fi
|
||
}
|
||
|
||
export UTOOLS_EDATE
|
||
function __edate() { [ -n "$UTOOLS_EDATE" ] && date +"[%d/%m/%Y-%H:%M:%S] "; }
|
||
|
||
export UTOOLS_ELOG_OVERWRITE
|
||
function __set_no_colors() { :; }
|
||
function elogto() {
|
||
UTOOLS_EDATE=1
|
||
if [ -n "$1" -a -n "$2" ]; then
|
||
LANG=fr_FR.UTF8
|
||
UTOOLS_OUTPUT_ENCODING="$UTF8"
|
||
__set_no_colors 1
|
||
if [ -n "$UTOOLS_ELOG_OVERWRITE" ]; then
|
||
exec >"$1" 2>"$2"
|
||
else
|
||
exec >>"$1" 2>>"$2"
|
||
fi
|
||
elif [ -n "$1" ]; then
|
||
LANG=fr_FR.UTF8
|
||
UTOOLS_OUTPUT_ENCODING="$UTF8"
|
||
__set_no_colors 1
|
||
if [ -n "$UTOOLS_ELOG_OVERWRITE" ]; then
|
||
exec >"$1" 2>&1
|
||
else
|
||
exec >>"$1" 2>&1
|
||
fi
|
||
fi
|
||
}
|
||
|
||
export __estack __tlevel
|
||
function __indent() {
|
||
if [ "${1/
|
||
/}" != "$1" ]; then
|
||
sed "2,\$s/^/${__tlevel}/g" <<<"$1"
|
||
else
|
||
rawecho "$1"
|
||
fi
|
||
}
|
||
function __eerror() { tooenc "$(__edate)${__tlevel}* error: $(__indent "$1")"; }
|
||
function __ewarn() { tooenc "$(__edate)${__tlevel}* warning: $(__indent "$1")"; }
|
||
function __enote() { tooenc "$(__edate)${__tlevel}* note: $(__indent "$1")"; }
|
||
function __ebanner() {
|
||
local maxi="${COLUMNS:-80}"
|
||
local -a lines
|
||
local psfix line
|
||
|
||
psfix="$(__edate)${__tlevel}"
|
||
while [ ${#psfix} -lt $maxi ]; do psfix="$psfix="; done
|
||
|
||
tooenc "$psfix"
|
||
maxi=$(($maxi - 1))
|
||
array_from_xlines lines "$1"
|
||
for line in "" "${lines[@]}" ""; do
|
||
line="$(__edate)${__tlevel}= $line"
|
||
if [ ${#line} -le $maxi ]; then
|
||
while [ ${#line} -lt $maxi ]; do line="$line "; done
|
||
line="$line="
|
||
fi
|
||
tooenc "$line"
|
||
done
|
||
tooenc "$psfix"
|
||
}
|
||
function __eimportant() { tooenc "$(__edate)${__tlevel}* important: $(__indent "$1")"; }
|
||
function __eattention() { tooenc "$(__edate)${__tlevel}* attention: $(__indent "$1")"; }
|
||
function __einfo() { tooenc "$(__edate)${__tlevel}* info: $(__indent "$1")"; }
|
||
function __eecho() { tooenc "$(__edate)${__tlevel}$(__indent "$1")"; }
|
||
function __eecho_() { tooenc_ "$(__edate)${__tlevel}$(__indent "$1")"; }
|
||
function __edebug() { tooenc "$(__edate)${__tlevel}* debug: $(__indent "$1")"; }
|
||
function __estep() { tooenc "$(__edate)${__tlevel}* $(__indent "$1")"; }
|
||
function __estepe() { __estep "$@"; }
|
||
function __estepw() { __estep "$@"; }
|
||
function __estepn() { __estep "$@"; }
|
||
function __estepi() { __estep "$@"; }
|
||
function __estep_() { tooenc_ "$(__edate)${__tlevel}* $(__indent "$1")"; }
|
||
function __estepe_() { __estep_ "$@"; }
|
||
function __estepw_() { __estep_ "$@"; }
|
||
function __estepn_() { __estep_ "$@"; }
|
||
function __estepi_() { __estep_ "$@"; }
|
||
function __etitle() { tooenc "$(__edate)${__tlevel}+++ $(__indent "$1")"; }
|
||
function __ebegin() { tooenc_ "$(__edate)${__tlevel}* $(__indent "$1"): "; }
|
||
function __edoto() { echo_ "."; }
|
||
function __edotw() { echo_ "w"; }
|
||
function __edotx() { echo_ "x"; }
|
||
function __edotp() { echo_ "+"; }
|
||
function __edotd() { tooenc "($1)"; }
|
||
function __eendo() { echo "[ok]"; }
|
||
function __eendx() { echo "[error]"; }
|
||
PRETTYOPTS=()
|
||
function set_verbosity() { :;}
|
||
function set_interaction() { :;}
|
||
function show_error() {
|
||
return 0
|
||
}
|
||
function show_warn() {
|
||
return 0
|
||
}
|
||
function show_info() {
|
||
return 0
|
||
}
|
||
function show_verbose() {
|
||
return 0
|
||
}
|
||
function show_debug() {
|
||
[ -n "$DEBUG" ]
|
||
}
|
||
function check_verbosity() {
|
||
return 0
|
||
}
|
||
function get_verbosity_option() { :;}
|
||
function check_interaction() {
|
||
return 0
|
||
}
|
||
function is_interaction() {
|
||
return 1
|
||
}
|
||
function get_interaction_option() { :;}
|
||
__epending=
|
||
function eflush() {
|
||
if [ -n "$__epending" ]; then rawecho "$__epending" 1>&2; __epending=; fi
|
||
}
|
||
function eclearp() {
|
||
__epending=
|
||
}
|
||
function eerror() {
|
||
show_error || return; eflush; __eerror "$*" 1>&2
|
||
}
|
||
function ewarn() {
|
||
show_warn || return; eflush; __ewarn "$*" 1>&2
|
||
}
|
||
function enote() {
|
||
show_info || return; eflush; __enote "$*" 1>&2
|
||
}
|
||
function ebanner() {
|
||
show_error || return; eflush; __ebanner "$*" 1>&2; sleep 5
|
||
}
|
||
function eimportant() {
|
||
show_error || return; eflush; __eimportant "$*" 1>&2
|
||
}
|
||
function eattention() {
|
||
show_warn || return; eflush; __eattention "$*" 1>&2
|
||
}
|
||
function einfo() {
|
||
show_info || return; eflush; __einfo "$*" 1>&2
|
||
}
|
||
function eecho() {
|
||
show_info || return; eflush; __eecho "$*" 1>&2
|
||
}
|
||
function eecho_() {
|
||
show_info || return; eflush; __eecho_ "$*" 1>&2
|
||
}
|
||
function edebug() {
|
||
show_debug || return; eflush; __edebug "$*" 1>&2
|
||
}
|
||
function trace() {
|
||
local r cmd="$(quoted_args "$@")"
|
||
show_info && { eflush; __eecho "\$ $cmd" 1>&2; }
|
||
"$@"; r=$?
|
||
if [ $r -ne 0 ]; then
|
||
if show_info; then
|
||
eflush; __eecho "^ [EC #$r]" 1>&2
|
||
elif show_error; then
|
||
eflush; __eecho "^ $cmd [EC #$r]" 1>&2;
|
||
fi
|
||
fi
|
||
return $r
|
||
}
|
||
function trace_error() {
|
||
local r
|
||
"$@"; r=$?
|
||
if [ $r -ne 0 ]; then
|
||
local cmd="$(quoted_args "$@")"
|
||
show_error && { eflush; __eecho "^ $cmd [EC #$r]" 1>&2; }
|
||
fi
|
||
return $r
|
||
}
|
||
|
||
function etitle() {
|
||
local __t_deferred=
|
||
__t_etitle "$@"
|
||
}
|
||
function etitled() {
|
||
local __t_deferred=1
|
||
__t_etitle "$@"
|
||
}
|
||
function __t_etitle() {
|
||
local __t_eend=default
|
||
local __t_clearp=
|
||
while [ -n "$1" ]; do
|
||
if [ "$1" == "--" ]; then
|
||
shift
|
||
break
|
||
elif [ "$1" == "-s" ]; then
|
||
__t_eend=
|
||
shift
|
||
elif [ "$1" == "--eend" ]; then
|
||
__t_eend=1
|
||
shift
|
||
elif [ "$1" == "-p" ]; then
|
||
__t_clearp=1
|
||
shift
|
||
else
|
||
break
|
||
fi
|
||
done
|
||
local __t_title="$1"; shift
|
||
local __t_s=0
|
||
[ -n "$__estack" ] && __tlevel="${__tlevel} "
|
||
__estack="$__estack:t"
|
||
if show_info; then
|
||
if [ -n "$__t_deferred" ]; then
|
||
__epending="${__epending:+$__epending
|
||
}$(__etitle "$__t_title")"
|
||
else
|
||
eflush
|
||
__etitle "$__t_title" 1>&2
|
||
fi
|
||
fi
|
||
if [ -n "$*" ]; then
|
||
"$@"
|
||
__t_s=$?
|
||
[ "$__t_eend" == "default" ] && __t_eend=1
|
||
fi
|
||
[ "$__t_eend" == "default" ] && __t_eend=
|
||
if [ -n "$__t_eend" ]; then
|
||
eend $__t_s
|
||
[ -n "$__t_clearp" ] && eclearp
|
||
fi
|
||
return $__t_s
|
||
}
|
||
function estep() {
|
||
show_info || return; eflush; __estep "$*" 1>&2
|
||
}
|
||
function estepe() {
|
||
show_info || return; eflush; __estepe "$*" 1>&2
|
||
}
|
||
function estepw() {
|
||
show_info || return; eflush; __estepw "$*" 1>&2
|
||
}
|
||
function estepn() {
|
||
show_info || return; eflush; __estepn "$*" 1>&2
|
||
}
|
||
function estepi() {
|
||
show_info || return; eflush; __estepi "$*" 1>&2
|
||
}
|
||
function estep_() {
|
||
show_info || return; eflush; __estep_ "$*" 1>&2
|
||
}
|
||
function estepe_() {
|
||
show_info || return; eflush; __estepe_ "$*" 1>&2
|
||
}
|
||
function estepw_() {
|
||
show_info || return; eflush; __estepw_ "$*" 1>&2
|
||
}
|
||
function estepn_() {
|
||
show_info || return; eflush; __estepn_ "$*" 1>&2
|
||
}
|
||
function estepi_() {
|
||
show_info || return; eflush; __estepi_ "$*" 1>&2
|
||
}
|
||
function ebegin() {
|
||
local __b_eend=default
|
||
while [ -n "$1" ]; do
|
||
if [ "$1" == "--" ]; then
|
||
shift
|
||
break
|
||
elif [ "$1" == "-s" ]; then
|
||
__b_eend=
|
||
shift
|
||
elif [ "$1" == "--eend" ]; then
|
||
__b_eend=1
|
||
shift
|
||
else
|
||
break
|
||
fi
|
||
done
|
||
local __b_msg="$1"; shift
|
||
local __b_s=0
|
||
__estack="$__estack:b"
|
||
if show_info; then
|
||
eflush
|
||
__ebegin "$__b_msg" 1>&2
|
||
fi
|
||
if [ -n "$*" ]; then
|
||
"$@"
|
||
__b_s=$?
|
||
[ "$__b_eend" == "default" ] && __b_eend=1
|
||
fi
|
||
[ "$__b_eend" == "default" ] && __b_eend=
|
||
[ -n "$__b_eend" ] && eend $__b_s
|
||
return $__b_s
|
||
}
|
||
function edot() {
|
||
local s=$?
|
||
show_info || return
|
||
eflush
|
||
[ -n "$1" ] && s="$1"
|
||
shift
|
||
if [ "$s" == "0" ]; then
|
||
__edoto 1>&2
|
||
else
|
||
__edotx 1>&2
|
||
fi
|
||
show_verbose && [ -n "$*" ] && __edotd "$*" 1>&2
|
||
return $s
|
||
}
|
||
function edotw() {
|
||
local s=$?
|
||
show_info || return
|
||
eflush
|
||
[ -n "$1" ] && s="$1"
|
||
shift
|
||
__edotw 1>&2
|
||
show_verbose && [ -n "$*" ] && __edotd "$*" 1>&2
|
||
return $s
|
||
}
|
||
function ewait() {
|
||
[ -n "$1" ] || return 1
|
||
if show_info; then
|
||
local count=2
|
||
eflush
|
||
little_sleep # certains processus retournent tout de suite
|
||
while is_running "$1"; do
|
||
sleep 1
|
||
if [ $count -gt 0 ]; then
|
||
count=$(($count - 1))
|
||
else
|
||
__edotp 1>&2
|
||
fi
|
||
done
|
||
__edoto 1>&2
|
||
else
|
||
wait "$1"
|
||
fi
|
||
}
|
||
function eend() {
|
||
local s=$?
|
||
if [ "$1" == "-c" ]; then
|
||
__estack=
|
||
__tlevel=
|
||
elif [ "${__estack%:b}" != "$__estack" ]; then
|
||
__estack="${__estack%:b}"
|
||
show_info || return
|
||
eflush
|
||
[ -n "$1" ] && s="$1"
|
||
if [ "$s" == "0" ]; then
|
||
__eendo 1>&2
|
||
else
|
||
__eendx 1>&2
|
||
fi
|
||
elif [ "${__estack%:t}" != "$__estack" ]; then
|
||
__estack="${__estack%:t}"
|
||
__tlevel="${__tlevel% }"
|
||
fi
|
||
}
|
||
function ask_yesno() {
|
||
local interactive=1
|
||
if [[ "$1" == -* ]]; then
|
||
if [ "$1" != -- ]; then
|
||
check_interaction "$1" || interactive=
|
||
fi
|
||
shift
|
||
else
|
||
check_interaction -c || interactive=
|
||
fi
|
||
local default="${2:-N}"
|
||
if [ "$default" == "C" ]; then
|
||
[ -n "$interactive" ] && default=N || default=O
|
||
elif [ "$default" == "X" ]; then
|
||
[ -n "$interactive" ] && default=O || default=N
|
||
fi
|
||
if [ -n "$interactive" ]; then
|
||
eflush
|
||
local message="$1"
|
||
local prompt="[oN]"
|
||
local r
|
||
is_yes "$default" && prompt="[On]"
|
||
if [ -n "$message" ]; then
|
||
tooenc_ "$message" 1>&2
|
||
else
|
||
tooenc_ "Voulez-vous continuer?" "$UTF8" 1>&2
|
||
fi
|
||
tooenc_ " $prompt " "$UTF8" 1>&2
|
||
uread r
|
||
is_yes "${r:-$default}"
|
||
else
|
||
is_yes "$default"
|
||
fi
|
||
}
|
||
function read_value() {
|
||
local -a __rv_opts
|
||
__rv_opts=()
|
||
__rv_read "$@"
|
||
}
|
||
function read_password() {
|
||
local -a __rv_opts
|
||
__rv_opts=(-s)
|
||
__rv_read "$@"
|
||
echo ""
|
||
}
|
||
function __rv_read() {
|
||
local __rv_int=1
|
||
if [[ "$1" == -* ]]; then
|
||
if [ "$1" != -- ]; then
|
||
check_interaction "$1" || __rv_int=
|
||
fi
|
||
shift
|
||
else
|
||
check_interaction -c || __rv_int=
|
||
fi
|
||
local __rv_msg="$1" __rv_v="${2:-value}" __rv_d="$3" __rv_re="${4:-O}"
|
||
if [ -z "$__rv_int" ]; then
|
||
if is_yes "$__rv_re" && [ -z "$__rv_d" ]; then
|
||
OENC="$UTF8" eerror "La valeur par défaut de $__rv_v doit être non vide"
|
||
return 1
|
||
fi
|
||
set_var "$__rv_v" "$__rv_d"
|
||
return 0
|
||
fi
|
||
|
||
eflush
|
||
local __rv_r
|
||
while true; do
|
||
if [ -n "$__rv_msg" ]; then
|
||
tooenc_ "$__rv_msg" 1>&2
|
||
else
|
||
tooenc_ "Entrez la valeur" "$UTF8" 1>&2
|
||
fi
|
||
[ -n "$__rv_d" ] && tooenc_ " [$__rv_d]" 1>&2
|
||
tooenc_ ": " "$UTF8" 1>&2
|
||
uread "${__rv_opts[@]}" __rv_r
|
||
__rv_r="${__rv_r:-$__rv_d}"
|
||
if [ -n "$__rv_r" ] || ! is_yes "$__rv_re"; then
|
||
set_var "$__rv_v" "$__rv_r"
|
||
return 0
|
||
fi
|
||
done
|
||
}
|
||
function simple_menu() {
|
||
local __sm_title= __sm_yourchoice= __sm_default=
|
||
local -a __sm_args
|
||
parse_opts -t: __sm_title -m: __sm_yourchoice -d: __sm_default @ __sm_args -- "$@" &&
|
||
set -- "${__sm_args[@]}" || ewarn "$__sm_args"
|
||
|
||
local __sm_option_var="${1:-option}" __sm_options_var="${2:-options}"
|
||
local __sm_option __sm_options
|
||
__sm_options="$__sm_options_var[*]"
|
||
if [ -z "${!__sm_options}" ]; then
|
||
OENC="$UTF8" eerror "Le tableau $__sm_options_var doit être non vide"
|
||
return 1
|
||
fi
|
||
[ -z "$__sm_default" ] && __sm_default="${!__sm_option_var}"
|
||
|
||
eflush
|
||
array_copy __sm_options "$__sm_options_var"
|
||
local __sm_c=0 __sm_i __sm_choice
|
||
while true; do
|
||
if [ "$__sm_c" == "0" ]; then
|
||
[ -n "$__sm_title" ] && tooenc "=== $__sm_title ===" 1>&2
|
||
__sm_i=1
|
||
for __sm_option in "${__sm_options[@]}"; do
|
||
if [ "$__sm_option" == "$__sm_default" ]; then
|
||
tooenc "$__sm_i*- $__sm_option" 1>&2
|
||
else
|
||
tooenc "$__sm_i - $__sm_option" 1>&2
|
||
fi
|
||
let __sm_i=$__sm_i+1
|
||
done
|
||
fi
|
||
|
||
if [ -n "$__sm_yourchoice" ]; then
|
||
tooenc_ "$__sm_yourchoice" 1>&2
|
||
else
|
||
tooenc_ "Entrez le numéro de l'option choisie" "$UTF8" 1>&2
|
||
fi
|
||
tooenc_ ": " "$UTF8" 1>&2
|
||
uread __sm_choice
|
||
|
||
if [ -z "$__sm_choice" -a -n "$__sm_default" ]; then
|
||
__sm_option="$__sm_default"
|
||
break
|
||
fi
|
||
if [ -n "$__sm_choice" -a -z "${__sm_choice//[0-9]/}" ]; then
|
||
if [ "$__sm_choice" -gt 0 -a "$__sm_choice" -le "${#__sm_options[*]}" ]; then
|
||
__sm_option="${__sm_options[$(($__sm_choice - 1))]}"
|
||
break
|
||
else
|
||
OENC="$UTF8" eerror "Numéro d'option incorrect"
|
||
fi
|
||
else
|
||
OENC="$UTF8" eerror "Vous devez saisir le numéro de l'option choisie"
|
||
fi
|
||
|
||
let __sm_c=$__sm_c+1
|
||
if [ "$__sm_c" -eq 5 ]; then
|
||
tooenc "" "$UTF8" 1>&2
|
||
__sm_c=0
|
||
fi
|
||
done
|
||
set_var "$__sm_option_var" "$__sm_option"
|
||
}
|
||
|
||
|
||
function __ac_forgetall() { __ac_files=(); }
|
||
__ac_forgetall
|
||
function __ac_trap() {
|
||
local file
|
||
for file in "${__ac_files[@]}"; do
|
||
[ -e "$file" ] && rm -rf "$file" 2>/dev/null
|
||
done
|
||
__ac_forgetall
|
||
}
|
||
trap __ac_trap 1 3 15 EXIT
|
||
function autoclean() {
|
||
local file
|
||
for file in "$@"; do
|
||
[ -n "$file" ] && array_add __ac_files "$file"
|
||
done
|
||
}
|
||
function ac_cleanall() {
|
||
__ac_trap
|
||
}
|
||
function ac_clean() {
|
||
local file
|
||
for file in "$@"; do
|
||
if array_contains __ac_files "$file"; then
|
||
[ -e "$file" ] && rm -rf "$file" 2>/dev/null
|
||
array_del __ac_files "$file"
|
||
fi
|
||
done
|
||
}
|
||
function ac_set_tmpfile() {
|
||
local __acst_d
|
||
if show_debug; then
|
||
if [ -n "$5" ]; then
|
||
is_yes "${!5}" && __acst_d=1
|
||
else
|
||
__acst_d=1
|
||
fi
|
||
fi
|
||
if [ -n "$__acst_d" -a -n "$3" ]; then
|
||
set_var "$1" "$3"
|
||
[ -f "$3" -a "$4" == keep ] || >"$3"
|
||
else
|
||
local __acst_t="$(mktempf "$2")"
|
||
autoclean "$__acst_t"
|
||
set_var "$1" "$__acst_t"
|
||
fi
|
||
}
|
||
function ac_set_tmpdir() {
|
||
local __acst_d
|
||
if show_debug; then
|
||
if [ -n "$4" ]; then
|
||
is_yes "${!4}" && __acst_d=1
|
||
else
|
||
__acst_d=1
|
||
fi
|
||
fi
|
||
if [ -n "$__acst_d" -a -n "$3" ]; then
|
||
set_var "$1" "$3"
|
||
mkdir -p "$3"
|
||
else
|
||
local __acst_t="$(mktempd "$2")"
|
||
autoclean "$__acst_t"
|
||
set_var "$1" "$__acst_t"
|
||
fi
|
||
}
|
||
function debug_tee() {
|
||
if show_debug; then
|
||
tee "$@"
|
||
else
|
||
cat
|
||
fi
|
||
}
|
||
|
||
|
||
function get_defaults_files() {
|
||
local __gd_dest="${1:-defaults}"; shift
|
||
local -a __gd_fs
|
||
local __gd_f __gd_found
|
||
for __gd_f in "$@"; do
|
||
__gd_found=
|
||
if [ -r "/etc/default/$__gd_f" ]; then
|
||
__gd_fs=("${__gd_fs[@]}" "/etc/default/$__gd_f")
|
||
__gd_found=1
|
||
fi
|
||
if [ -r "$HOME/etc/default/$__gd_f" ]; then
|
||
__gd_fs=("${__gd_fs[@]}" "$HOME/etc/default/$__gd_f")
|
||
__gd_found=1
|
||
fi
|
||
if [ -z "$__gd_found" -a -r "$scriptdir/lib/default/$__gd_f" ]; then
|
||
__gd_fs=("${__gd_fs[@]}" "$scriptdir/lib/default/$__gd_f")
|
||
fi
|
||
done
|
||
array_copy "$__gd_dest" __gd_fs
|
||
}
|
||
|
||
function set_defaults() {
|
||
local -a __sd_fs
|
||
local __sd_f
|
||
get_defaults_files __sd_fs "$@"
|
||
for __sd_f in "${__sd_fs[@]}"; do
|
||
source "$__sd_f"
|
||
done
|
||
}
|
||
|
||
|
||
: "${MYHOST:=$HOSTNAME}"
|
||
: "${MYHOSTNAME:=${MYHOST%%.*}}"
|
||
export MYHOST MYHOSTNAME
|
||
|
||
function myhost() {
|
||
hostname -f 2>/dev/null || echo "$MYHOST"
|
||
}
|
||
function myhostname() {
|
||
hostname -s 2>/dev/null || echo "$MYHOSTNAME"
|
||
}
|
||
##@inc]base
|
||
##@inc[pretty
|
||
## Affichage en couleur, et support de niveaux de "verbosité" et d'interaction
|
||
##@require base
|
||
uprovide pretty
|
||
urequire base
|
||
|
||
|
||
function __get_color() {
|
||
[ -z "$*" ] && set RESET
|
||
echo_ $'\e['
|
||
local sep
|
||
while [ -n "$1" ]; do
|
||
[ -n "$sep" ] && echo_ ";"
|
||
case "$1" in
|
||
z|RESET) echo_ "0";;
|
||
o|BLACK) echo_ "30";;
|
||
r|RED) echo_ "31";;
|
||
g|GREEN) echo_ "32";;
|
||
y|YELLOW) echo_ "33";;
|
||
b|BLUE) echo_ "34";;
|
||
m|MAGENTA) echo_ "35";;
|
||
c|CYAN) echo_ "36";;
|
||
w|WHITE) echo_ "37";;
|
||
DEFAULT) echo_ "39";;
|
||
O|BLACK_BG) echo_ "40";;
|
||
R|RED_BG) echo_ "41";;
|
||
G|GREEN_BG) echo_ "42";;
|
||
Y|YELLOW_BG) echo_ "43";;
|
||
B|BLUE_BG) echo_ "44";;
|
||
M|MAGENTA_BG) echo_ "45";;
|
||
C|CYAN_BG) echo_ "46";;
|
||
W|WHITE_BG) echo_ "47";;
|
||
DEFAULT_BG) echo_ "49";;
|
||
@|BOLD) echo_ "1";;
|
||
-|FAINT) echo_ "2";;
|
||
_|UNDERLINED) echo_ "4";;
|
||
~|REVERSE) echo_ "7";;
|
||
n|NORMAL) echo_ "22";;
|
||
esac
|
||
sep=1
|
||
shift
|
||
done
|
||
echo_ "m"
|
||
}
|
||
function get_color() {
|
||
[ -n "$NO_COLORS" ] && return
|
||
__get_color "$@"
|
||
}
|
||
function __set_no_colors() {
|
||
if [ -z "$1" ]; then
|
||
if [ -n "$UTOOLS_NO_COLORS" ]; then NO_COLORS=1
|
||
elif out_isatty && err_isatty; then NO_COLORS=
|
||
else NO_COLORS=1
|
||
fi
|
||
else
|
||
is_yes "$1" && NO_COLORS=1 || NO_COLORS=
|
||
fi
|
||
COULEUR_ROUGE="$(get_color RED BOLD)"
|
||
COULEUR_VERTE="$(get_color GREEN BOLD)"
|
||
COULEUR_JAUNE="$(get_color YELLOW BOLD)"
|
||
COULEUR_BLEUE="$(get_color BLUE BOLD)"
|
||
COULEUR_BLANCHE="$(get_color WHITE BOLD)"
|
||
COULEUR_NORMALE="$(get_color RESET)"
|
||
}
|
||
__set_no_colors
|
||
|
||
function __eerror() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}* error:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __ewarn() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}* warning:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __enote() { tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}* note:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __ebanner() {
|
||
local maxi="${COLUMNS:-80}"
|
||
local -a lines
|
||
local psfix line
|
||
|
||
psfix="$(__edate)${__tlevel}"
|
||
while [ ${#psfix} -lt $maxi ]; do psfix="$psfix="; done
|
||
|
||
tooenc "$COULEUR_ROUGE$psfix"
|
||
maxi=$(($maxi - 1))
|
||
array_from_xlines lines "$1"
|
||
for line in "" "${lines[@]}" ""; do
|
||
line="$(__edate)${__tlevel}= $line"
|
||
if [ ${#line} -le $maxi ]; then
|
||
while [ ${#line} -lt $maxi ]; do line="$line "; done
|
||
line="$line="
|
||
fi
|
||
tooenc "$line"
|
||
done
|
||
tooenc "$psfix$COULEUR_NORMALE"
|
||
}
|
||
function __eimportant() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}* important:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __eattention() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}* attention:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __einfo() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}* info:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __edebug() { tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}* debug:${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estep() { tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepe() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepw() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepn() { tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepi() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estep_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepe_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_ROUGE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepw_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepn_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_VERTE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __estepi_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLEUE}*${COULEUR_NORMALE} $(__indent "$1")"; }
|
||
function __etitle() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}+++ $(get_color _)$(__indent "$1")${COULEUR_NORMALE}"; }
|
||
function __ebegin() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1"): "; }
|
||
function __edoto() { echo_ "."; }
|
||
function __edotw() { echo_ "${COULEUR_JAUNE}w${COULEUR_NORMALE}"; }
|
||
function __edotx() { echo_ "${COULEUR_ROUGE}x${COULEUR_NORMALE}"; }
|
||
function __edotp() { echo_ "${COULEUR_JAUNE}+${COULEUR_NORMALE}"; }
|
||
function __edotd() { tooenc "($1)"; }
|
||
function __eendo() { echo "${COULEUR_VERTE}[ok]${COULEUR_NORMALE}"; }
|
||
function __eendx() { echo "${COULEUR_ROUGE}[error]${COULEUR_NORMALE}"; }
|
||
|
||
export __verbosity
|
||
[ -z "$__verbosity" ] && __verbosity=3
|
||
function set_verbosity() {
|
||
[ -z "$__verbosity" ] && __verbosity=3
|
||
case "$1" in
|
||
-Q|--very-quiet) __verbosity=0;;
|
||
-q|--quiet) [ "$__verbosity" -gt 0 ] && let __verbosity=$__verbosity-1;;
|
||
-v|--verbose) [ "$__verbosity" -lt 5 ] && let __verbosity=$__verbosity+1;;
|
||
-c|--default) __verbosity=3;;
|
||
-D|--debug) __verbosity=5; DEBUG=1;;
|
||
*) return 1;;
|
||
esac
|
||
return 0
|
||
}
|
||
export __interaction
|
||
[ -z "$__interaction" ] && __interaction=2
|
||
function set_interaction() {
|
||
[ -z "$__interaction" ] && __interaction=2
|
||
case "$1" in
|
||
-b|--batch) __interaction=0;;
|
||
-y|--automatic) [ "$__interaction" -gt 0 ] && let __interaction=$__interaction-1;;
|
||
-i|--interactive) [ "$__interaction" -lt 3 ] && let __interaction=$__interaction+1;;
|
||
-c|--default) __interaction=2;;
|
||
*) return 1;;
|
||
esac
|
||
return 0
|
||
}
|
||
PRETTYOPTS=(
|
||
-L:,--log-to: '$elogto $value_'
|
||
-Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_'
|
||
-b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_'
|
||
)
|
||
|
||
function show_error() { [ "$__verbosity" -ge 1 ]; }
|
||
function show_warn() { [ "$__verbosity" -ge 2 ]; }
|
||
function show_info() { [ "$__verbosity" -ge 3 ]; }
|
||
function show_verbose() { [ "$__verbosity" -ge 4 ]; }
|
||
function show_debug() { [ -n "$DEBUG" -o "$__verbosity" -ge 5 ]; }
|
||
function check_verbosity() {
|
||
case "$1" in
|
||
-Q|--very-quiet) [ "$__verbosity" -ge 1 ];;
|
||
-q|--quiet) [ "$__verbosity" -ge 2 ];;
|
||
-c|--default) [ "$__verbosity" -ge 3 ];;
|
||
-v|--verbose) [ "$__verbosity" -ge 4 ];;
|
||
-D|--debug) [ -n "$DEBUG" -o "$__verbosity" -ge 5 ];;
|
||
*) return 0;;
|
||
esac
|
||
}
|
||
function get_verbosity_option() {
|
||
case "$__verbosity" in
|
||
0) echo --very-quiet;;
|
||
1) echo --quiet --quiet;;
|
||
2) echo --quiet;;
|
||
4) echo --verbose;;
|
||
5) echo --debug;;
|
||
esac
|
||
}
|
||
function check_interaction() {
|
||
case "$1" in
|
||
-b|--batch) return 0;;
|
||
-y|--automatic) [ -n "$__interaction" -a "$__interaction" -ge 1 ];;
|
||
-c|--default) [ -n "$__interaction" -a "$__interaction" -ge 2 ];;
|
||
-i|--interactive) [ -n "$__interaction" -a "$__interaction" -ge 3 ];;
|
||
*) return 0;;
|
||
esac
|
||
}
|
||
function is_interaction() {
|
||
case "$1" in
|
||
-b|--batch) [ -n "$__interaction" -a "$__interaction" -eq 0 ];;
|
||
-Y) [ -n "$__interaction" -a "$__interaction" -le 1 ];;
|
||
-y|--automatic) [ -n "$__interaction" -a "$__interaction" -eq 1 ];;
|
||
-c|--default) [ -n "$__interaction" -a "$__interaction" -eq 2 ];;
|
||
-i|--interactive) [ -n "$__interaction" -a "$__interaction" -eq 3 ];;
|
||
-C) [ -n "$__interaction" -a "$__interaction" -ge 2 ];;
|
||
*) return 1;;
|
||
esac
|
||
}
|
||
function get_interaction_option() {
|
||
case "$__interaction" in
|
||
0) echo --batch;;
|
||
1) echo --automatic;;
|
||
3) echo --interactive;;
|
||
esac
|
||
}
|
||
|
||
##@inc]pretty
|
||
##@inc[sysinfos
|
||
## Gestion des informations sur l'hôte local
|
||
##@require base
|
||
uprovide sysinfos
|
||
urequire base
|
||
|
||
|
||
SYSNAMES=(linux linux64 linux32 linuxppc64 linuxppc32 linuxarm macosx)
|
||
linux_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo)
|
||
linux32_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo)
|
||
linux64_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo)
|
||
linuxppc32_SYSDISTS=(debianlike debian ubuntu redhatlike fedora)
|
||
linuxppc64_SYSDISTS=(debianlike debian ubuntu redhatlike fedora)
|
||
linuxarm_SYSDISTS=(debianlike debian ubuntu)
|
||
macosx_SYSDISTS=(lion snowleopard leopard tiger panther)
|
||
SYSDIST_ALIASES=(
|
||
10.7=lion 10.6=snowleopard 10.5=leopard 10.4=tiger 10.3=panther
|
||
)
|
||
debianlike_SYSVERS=()
|
||
debian_SYSVERS=(wheezy squeeze lenny etch)
|
||
ubuntu_SYSVERS=(oneiric natty maverick lucid karmic jaunty intrepid hardy)
|
||
redhatlike_SYSVERS=()
|
||
rhel_SYSVERS=(rhel6 rhel5 rhel4 redhat6 redhat5 redhat4)
|
||
fedora_SYSVERS=(fedora14 fedora13 fedora12 fedora11)
|
||
centos_SYSVERS=(centos6 centos5 centos4 redhat6 redhat5 redhat4)
|
||
suse_SYSVERS=()
|
||
gentoo_SYSVERS=()
|
||
SYSVER_ALIASES=(
|
||
7=wheezy 6=squeeze 5=lenny 4=etch
|
||
11.10=oneiric 11.04=natty 10.10=maverick 10.04=lucid 9.10=karmic 9.04=jaunty 8.10=intrepid 8.04=hardy
|
||
)
|
||
|
||
function __setup_ALL_SYSvars() {
|
||
local s ds d fs f
|
||
ALL_SYSDISTS=()
|
||
for s in "${SYSNAMES[@]}"; do
|
||
array_copy ds "${s}_SYSDISTS"
|
||
for d in "${ds[@]}"; do
|
||
array_set ALL_SYSDISTS "$d"
|
||
done
|
||
done
|
||
ALL_SYSVERS=()
|
||
for d in "${ALL_SYSDISTS[@]}"; do
|
||
array_copy fs "${d}_SYSVERS"
|
||
for f in "${fs[@]}"; do
|
||
array_contains ALL_SYSVERS "$f" && array_del ALL_SYSVERS "$f"
|
||
array_add ALL_SYSVERS "$f"
|
||
done
|
||
done
|
||
}
|
||
__setup_ALL_SYSvars
|
||
unset -f __setup_ALL_SYSvars
|
||
|
||
MYSYSNAME=()
|
||
MYBITS=
|
||
MYSYSDIST=()
|
||
MYSYSVER=()
|
||
if [ "$UNAME_SYSTEM" == "Linux" ]; then
|
||
case "$UNAME_MACHINE" in
|
||
x86_64)
|
||
MYSYSNAME=(linux64 linux)
|
||
MYBITS=64
|
||
;;
|
||
i386|i586|i686)
|
||
MYSYSNAME=(linux32 linux)
|
||
MYBITS=32
|
||
;;
|
||
ppc)
|
||
MYSYSNAME=(linuxppc32 linuxppc linux)
|
||
MYBITS=32
|
||
;;
|
||
ppc64)
|
||
MYSYSNAME=(linuxppc64 linuxppc linux)
|
||
MYBITS=64
|
||
;;
|
||
arm*)
|
||
MYSYSNAME=(linuxarm linux)
|
||
;;
|
||
*)
|
||
MYSYSNAME=(linux)
|
||
;;
|
||
esac
|
||
|
||
if [ -f /etc/debian_version ]; then
|
||
case "$(</etc/debian_version)" in
|
||
7*|wheezy*) MYSYSDIST=(debian debianlike); MYSYSVER=(wheezy);;
|
||
6*|squeeze*) MYSYSDIST=(debian debianlike); MYSYSVER=(squeeze);;
|
||
5*) MYSYSDIST=(debian debianlike); MYSYSVER=(lenny);;
|
||
4*) MYSYSDIST=(debian debianlike); MYSYSVER=(etch);;
|
||
*) MYSYSDIST=(debianlike);;
|
||
esac
|
||
elif [ -f /etc/gentoo-release ]; then
|
||
MYSYSDIST=(gentoo)
|
||
elif [ -f /etc/redhat-release ]; then
|
||
case "$(</etc/redhat-release)" in
|
||
Fedora*) MYSYSDIST=(fedora redhatlike);;
|
||
Red*Hat*Enterprise*Linux*) MYSYSDIST=(rhel redhatlike);;
|
||
CentOS*) MYSYSDIST=(centos redhatlike);;
|
||
*) MYSYSDIST=(redhatlike);;
|
||
esac
|
||
case "$(</etc/redhat-release)" in
|
||
Fedora*14*) MYSYSVER=(fedora14);;
|
||
Fedora*13*) MYSYSVER=(fedora13);;
|
||
Fedora*12*) MYSYSVER=(fedora12);;
|
||
Fedora*11*) MYSYSVER=(fedora11);;
|
||
Red*Hat*Enterprise*Linux*release\ 6*) MYSYSVER=(rhel6 redhat6);;
|
||
Red*Hat*Enterprise*Linux*release\ 5*) MYSYSVER=(rhel5 redhat5);;
|
||
Red*Hat*Enterprise*Linux*release\ 4*) MYSYSVER=(rhel4 redhat4);;
|
||
CentOS*release\ 6*) MYSYSVER=(centos6 redhat6);;
|
||
CentOS*release\ 5*) MYSYSVER=(centos5 redhat5);;
|
||
CentOS*release\ 4*) MYSYSVER=(centos4 redhat4);;
|
||
esac
|
||
fi
|
||
elif [ "$UNAME_SYSTEM" == "Darwin" ]; then
|
||
function get_macosx_version() {
|
||
local i
|
||
for i in /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist /System/Library/Frameworks/CoreServices.framework/Resources/version.plist; do
|
||
if [ -f "$i" ]; then
|
||
grep -A 1 CFBundleShortVersionString "$i" | grep string | sed 's/.*<string>//g
|
||
s/<\/string>.*$//g'
|
||
break
|
||
fi
|
||
done
|
||
}
|
||
MYSYSNAME=(macosx darwin)
|
||
case "$(get_macosx_version)" in
|
||
10.7*) MYSYSDIST=(lion);;
|
||
10.6*) MYSYSDIST=(snowleopard);;
|
||
10.5*) MYSYSDIST=(leopard);;
|
||
10.4*) MYSYSDIST=(tiger);;
|
||
10.3*) MYSYSDIST=(panther);;
|
||
esac
|
||
fi
|
||
if [ -n "$UTOOLS_CHROOT" ]; then
|
||
[ -n "$UTOOLS_SYSNAME" ] && eval "MYSYSNAME=($UTOOLS_SYSNAME)"
|
||
[ -n "$UTOOLS_BITS" ] && eval "MYBITS=$UTOOLS_BITS"
|
||
[ -n "$UTOOLS_SYSDIST" ] && eval "MYSYSDIST=($UTOOLS_SYSDIST)"
|
||
[ -n "$UTOOLS_SYSVER" ] && eval "MYSYSVER=($UTOOLS_SYSVER)"
|
||
fi
|
||
|
||
function __get_sysdist_alias() {
|
||
if ! array_contains ALL_SYSDISTS "$1"; then
|
||
local nd n d
|
||
for nd in "${SYSDIST_ALIASES[@]}"; do
|
||
splitvar "$nd" n d
|
||
if [ "$n" == "$1" ]; then
|
||
echo "$d"
|
||
return
|
||
fi
|
||
done
|
||
fi
|
||
echo "$1"
|
||
}
|
||
|
||
function __get_sysver_alias() {
|
||
if ! array_contains ALL_SYSVERS "$1"; then
|
||
local nv n v
|
||
for nv in "${SYSVER_ALIASES[@]}"; do
|
||
splitvar "$nv" n v
|
||
if [ "$n" == "$1" ]; then
|
||
echo "$v"
|
||
return
|
||
fi
|
||
done
|
||
fi
|
||
echo "$1"
|
||
}
|
||
|
||
function __fix_sysinfos_upward() {
|
||
local sysname_ sysdists_ sysdist_ sysvers_ sysver_
|
||
if [ -z "${!sysnamevar_}" ]; then
|
||
if [ -z "${!sysdistvar_}" ]; then
|
||
[ -z "${!sysvervar_}" ] && return
|
||
for sysname_ in "${SYSNAMES[@]}"; do
|
||
array_copy sysdists_ "${sysname_}_SYSDISTS"
|
||
for sysdist_ in "${sysdists_[@]}"; do
|
||
array_copy sysvers_ "${sysdist_}_SYSVERS"
|
||
for sysver_ in "${sysvers_[@]}"; do
|
||
if [ "$sysver_" == "${!sysvervar_}" ]; then
|
||
set_var "$sysdistvar_" "$sysdist_"
|
||
set_var "$sysnamevar_" "$sysname_"
|
||
return
|
||
fi
|
||
done
|
||
done
|
||
done
|
||
fi
|
||
[ -z "${!sysdistvar_}" ] && return 0
|
||
for sysname_ in "${SYSNAMES[@]}"; do
|
||
array_copy sysdists_ "${sysname_}_SYSDISTS"
|
||
for sysdist_ in "${sysdists_[@]}"; do
|
||
if [ "$sysdist_" == "${!sysdistvar_}" ]; then
|
||
set_var "$sysnamevar_" "$sysname_"
|
||
return
|
||
fi
|
||
done
|
||
done
|
||
fi
|
||
}
|
||
function __fix_sysinfos_downward() {
|
||
local sysname_ sysdist_ sysver_
|
||
|
||
[ -z "${!sysnamevar_}" ] && return
|
||
|
||
if [ -z "${!sysdistvar_}" ]; then
|
||
array_copy sysdists_ "${!sysnamevar_}_SYSDISTS"
|
||
for sysdist_ in "${sysdists_[@]}"; do
|
||
set_var "$sysdistvar_" "$sysdist_"
|
||
break
|
||
done
|
||
fi
|
||
[ -z "${!sysdistvar_}" ] && return
|
||
|
||
if [ -z "${!sysvervar_}" ]; then
|
||
array_copy sysvers_ "${sysdistvar_}_SYSVERS"
|
||
for sysver_ in "${sysvers_[@]}"; do
|
||
set_var "$sysvervar_" "$sysver_"
|
||
break
|
||
done
|
||
fi
|
||
}
|
||
function ensure_sysinfos() {
|
||
local sysnamevar_="${1:-SYSNAME}"
|
||
local sysdistvar_="${2:-SYSDIST}"
|
||
local sysvervar_="${3:-SYSVER}"
|
||
[ -n "${!sysdistvar_}" ] && set_var "$sysdistvar_" "$(__get_sysdist_alias "${!sysdistvar_}")"
|
||
[ -n "${!sysvervar_}" ] && set_var "$sysvervar_" "$(__get_sysver_alias "${!sysvervar_}")"
|
||
__fix_sysinfos_upward
|
||
__fix_sysinfos_downward
|
||
}
|
||
|
||
function check_sysinfos() {
|
||
local sysnamevar_="MYSYSNAME"
|
||
local sysdistvar_="MYSYSDIST"
|
||
local sysvervar_="MYSYSVER"
|
||
local bitsvar_="MYBITS"
|
||
local check_=sysname r_=0
|
||
while [ -n "$1" ]; do
|
||
if [[ "$1" == -* ]]; then
|
||
[ "$1" == "-S" ] && { sysnamevar_="$2"; shift 2; continue; }
|
||
[ "$1" == "-D" ] && { sysdistvar_="$2"; shift 2; continue; }
|
||
[ "$1" == "-V" ] && { sysvervar_="$2"; shift 2; continue; }
|
||
[ "$1" == "-B" ] && { bitsvar_="$2"; shift 2; continue; }
|
||
[ "$r_" == "1" ] && break
|
||
[ "$1" == "-s" ] && check_=sysname
|
||
[ "$1" == "-d" ] && check_=sysdist
|
||
[ "$1" == "-v" ] && check_=sysver
|
||
[ "$1" == "-b" ] && check_=bits
|
||
r_=1
|
||
shift
|
||
continue
|
||
fi
|
||
if [ "$check_" == "sysname" ]; then
|
||
if array_contains "$sysnamevar_" "$1"; then
|
||
r_=0
|
||
check_=skip
|
||
fi
|
||
|
||
elif [ "$check_" == "sysdist" ]; then
|
||
local mode_=exact value_="$1"
|
||
if [ "${value_%+}" != "$value_" ]; then
|
||
mode_=after
|
||
value_="${value_%+}"
|
||
elif [ "${value_%-}" != "$value_" ]; then
|
||
mode_=before
|
||
value_="${value_%-}"
|
||
fi
|
||
value_="$(__get_sysdist_alias "$value_")"
|
||
if [ "$mode_" == "exact" ]; then
|
||
if array_contains "$sysdistvar_" "$value_"; then
|
||
r_=0
|
||
check_=skip
|
||
fi
|
||
elif [ "$mode_" == "after" ]; then
|
||
local sysdist_
|
||
for sysdist_ in "${ALL_SYSDISTS[@]}"; do
|
||
if array_contains "$sysdistvar_" "$sysdist_"; then
|
||
r_=0
|
||
check_=skip
|
||
elif [ "$sysdist_" == "$value_" ]; then
|
||
break
|
||
fi
|
||
done
|
||
elif [ "$mode_" == "before" ]; then
|
||
local sysdist_ found_
|
||
for sysdist_ in "${ALL_SYSDISTS[@]}"; do
|
||
[ "$sysdist_" == "$value_" ] && found_=1
|
||
if [ -n "$found_" ]; then
|
||
if array_contains "$sysdistvar_" "$sysdist_"; then
|
||
r_=0
|
||
check_=skip
|
||
break
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
|
||
elif [ "$check_" == "sysver" ]; then
|
||
local mode_=exact value_="$1"
|
||
if [ "${value_%+}" != "$value_" ]; then
|
||
mode_=after
|
||
value_="${value_%+}"
|
||
elif [ "${value_%-}" != "$value_" ]; then
|
||
mode_=before
|
||
value_="${value_%-}"
|
||
fi
|
||
value_="$(__get_sysver_alias "$value_")"
|
||
if [ "$mode_" == "exact" ]; then
|
||
if array_contains "$sysvervar_" "$value_"; then
|
||
r_=0
|
||
check_=skip
|
||
fi
|
||
elif [ "$mode_" == "after" ]; then
|
||
local sysver_
|
||
for sysver_ in "${ALL_SYSVERS[@]}"; do
|
||
if array_contains "$sysvervar_" "$sysver_"; then
|
||
r_=0
|
||
check_=skip
|
||
elif [ "$sysver_" == "$value_" ]; then
|
||
break
|
||
fi
|
||
done
|
||
elif [ "$mode_" == "before" ]; then
|
||
local sysver_ found_
|
||
for sysver_ in "${ALL_SYSVERS[@]}"; do
|
||
[ "$sysver_" == "$value_" ] && found_=1
|
||
if [ -n "$found_" ]; then
|
||
if array_contains "$sysvervar_" "$sysver_"; then
|
||
r_=0
|
||
check_=skip
|
||
break
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
|
||
elif [ "$check_" == "bits" ]; then
|
||
if [ "$1" == "${!bitsvar_}" ]; then
|
||
r_=0
|
||
check_=skip
|
||
fi
|
||
fi
|
||
shift
|
||
done
|
||
return $r_
|
||
}
|
||
##@inc]sysinfos
|
||
##@inc[compat
|
||
# Code de support pour les architectures autre que Linux
|
||
##@require base
|
||
##@require sysinfos
|
||
uprovide compat
|
||
urequire base sysinfos
|
||
|
||
if check_sysinfos -s macosx; then
|
||
function __rlnp() { local p="$1" np f; [ "${p#/}" == "$p" ] && p="$(pwd)/$p"; while [[ "$p" == *//* ]]; do p="${p//\/\///}"; done; p="${p%/}"; p="${p#/}"; np=; while [ -n "$p" ]; do if [[ "$p" == */* ]]; then f="${p%%/*}"; p="${p#*/}"; else f="$p"; p=; fi; if [ "$f" == . ]; then :; elif [ "$f" == .. ]; then if [[ "$np" == */* ]]; then np="${np%/*}"; else np=; fi; else [ -n "$np" ] && np="$np/"; np="$np$f"; fi; done; echo "/$np"; }
|
||
function readlinkm() { local p="$(__rlnp "$1")" np n; while [ -n "$p" ]; do local max=50; while [ -L "$p" -a $max -gt 0 ]; do n="$(readlink "$p")"; if [ "${n#/}" != "$n" ]; then p="$n"; else p="${p%/*}/$n"; fi; p="$(__rlnp "$p")"; max=$(($max-1)); done; [ -n "$np" ] && np="/$np"; if [[ "$p" == */* ]]; then np="${p##*/}$np"; p="${p%/*}"; else np="$p$np"; p=; fi; done; echo "/$np"; }
|
||
function _nl2lf() { awk '{ sub(/\r$/, ""); gsub(/\r/, "\n"); print }'; }
|
||
function _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; }
|
||
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
|
||
function sedi() { sed -i '' "$@"; }
|
||
|
||
function __po_check_options() {
|
||
local -a options args
|
||
local option value flag
|
||
if [ "${opts_#+}" != "$opts_" ]; then
|
||
while [ -n "$*" ]; do
|
||
if [ "$1" == "--" ]; then
|
||
shift
|
||
break
|
||
elif [[ "$1" == --* ]]; then
|
||
option="${1%%=*}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
else
|
||
value=
|
||
fi
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
elif [[ "$1" == -* ]]; then
|
||
option="${1:0:2}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ -n "${1:2}" ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
else
|
||
break
|
||
fi
|
||
done
|
||
args=("$@")
|
||
elif [ "${opts_#-}" != "$opts_" ]; then
|
||
while [ -n "$*" ]; do
|
||
if [ "$1" == "--" ]; then
|
||
shift
|
||
break
|
||
elif [[ "$1" == --* ]]; then
|
||
option="${1%%=*}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
else
|
||
value=
|
||
fi
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
elif [[ "$1" == -* ]]; then
|
||
option="${1:0:2}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ -n "${1:2}" ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
else
|
||
options=("${options[@]}" "$1")
|
||
shift
|
||
fi
|
||
done
|
||
args=("$@")
|
||
else
|
||
while [ -n "$*" ]; do
|
||
if [ "$1" == "--" ]; then
|
||
shift
|
||
break
|
||
elif [[ "$1" == --* ]]; then
|
||
option="${1%%=*}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
else
|
||
value=
|
||
fi
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ "$1" == *=* ]]; then
|
||
value="${1#--*=}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
elif [[ "$1" == -* ]]; then
|
||
option="${1:0:2}"
|
||
if flag="$(array_find options_ "$option" flags_)"; then
|
||
if [[ "$flag" == ::* ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
options=("${options[@]}" "$option" "$value")
|
||
elif [[ "$flag" == :* ]]; then
|
||
if [[ -n "${1:2}" ]]; then
|
||
value="${1:2}"
|
||
shift
|
||
elif [ $# -gt 1 ]; then
|
||
value="$2"
|
||
shift 2
|
||
else
|
||
echo "option requires an argument: $option"
|
||
return 1
|
||
fi
|
||
options=("${options[@]}" "$option" "$value")
|
||
else
|
||
shift
|
||
options=("${options[@]}" "$option")
|
||
fi
|
||
else
|
||
echo "invalid option: $1"
|
||
return 1
|
||
fi
|
||
|
||
else
|
||
args=("${args[@]}" "$1")
|
||
shift
|
||
fi
|
||
done
|
||
args=("${args[@]}" "$@")
|
||
fi
|
||
quoted_args "${options[@]}" -- "${args[@]}"
|
||
return 0
|
||
}
|
||
|
||
function __pd_isleap() {
|
||
[ $(($1 % 4)) -eq 0 -a \( $(($1 % 100)) -ne 0 -o $(($1 % 400)) -eq 0 \) ]
|
||
}
|
||
function __pd_fix_month() {
|
||
local __pdfm_y="${!1}" __pdfm_m="${!2}"
|
||
let __pdfm_m=$__pdfm_m-1
|
||
while [ $__pdfm_m -gt 11 ]; do
|
||
let __pdfm_m=$__pdfm_m-12
|
||
let __pdfm_y=$__pdfm_y+1
|
||
done
|
||
while [ $__pdfm_m -lt 0 ]; do
|
||
let __pdfm_m=$__pdfm_m+12
|
||
let __pdfm_y=$__pdfm_y-1
|
||
done
|
||
let __pdfm_m=$__pdfm_m+1
|
||
eval "$1=$__pdfm_y; $2=$__pdfm_m"
|
||
}
|
||
__PD_MONTHDAYS=(0 31 28 31 30 31 30 31 31 30 31 30 31)
|
||
function __pd_monthdays() {
|
||
local y="$1" m="$2" mds
|
||
__pd_fix_month y m
|
||
mds="${__PD_MONTHDAYS[$m]}"
|
||
[ "$m" -eq 2 ] && __pd_isleap "$y" && let mds=$mds+1
|
||
echo $mds
|
||
}
|
||
function __pd_fix_day() {
|
||
local __pdfd_y="${!1}" __pdfd_m="${!2}" __pdfd_d="${!3}" __pdfd_mds
|
||
let __pdfd_d=$__pdfd_d-1
|
||
let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m)
|
||
while [ $__pdfd_d -gt $(($__pdfd_mds-1)) ]; do
|
||
let __pdfd_d=$__pdfd_d-$__pdfd_mds
|
||
let __pdfd_m=$__pdfd_m+1
|
||
__pd_fix_month __pdfd_y __pdfd_m
|
||
let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m)
|
||
done
|
||
while [ $__pdfd_d -lt 0 ]; do
|
||
let __pdfd_m=$__pdfd_m-1
|
||
__pd_fix_month __pdfd_y __pdfd_m
|
||
let __pdfd_d=$__pdfd_d-$(__pd_monthdays $__pdfd_y $__pdfd_m)
|
||
done
|
||
let __pdfd_d=$__pdfd_d+1
|
||
eval "$1=$__pdfd_y; $2=$__pdfd_m; $3=$__pdfd_d"
|
||
}
|
||
function __pd_fix_date() {
|
||
local __pdf_y="${!1}" __pdf_m="${!2}" __pdf_d="${!3}"
|
||
}
|
||
function parse_date() {
|
||
local value="$1" type="${2:-date}"
|
||
local d m y
|
||
eval "$(date +%d/%m/%Y | awk -F/ '{
|
||
print "d=" $1 "; m=" $2 "; y=" $3
|
||
}')"
|
||
if [ "${value#+}" != "$value" ]; then
|
||
d="$(($d+${value#+}))"
|
||
else
|
||
eval "$(<<<"$value" awkrun FS=/ dn="$dn" mn="$mn" yn="$yn" type="$type" '{
|
||
d = $1 + 0; if (d < 1) d = dn + 0;
|
||
m = $2 + 0; if (m < 1) m = mn + 0;
|
||
if ($3 == "") y = yn + 0;
|
||
else { y = $3 + 0; if (y < 100) y = y + 2000; }
|
||
print "d=" d "; m=" m "; y=" y
|
||
}')"
|
||
fi
|
||
__pd_fix_month y m
|
||
__pd_fix_day y m d
|
||
case "$type" in
|
||
d|date)
|
||
awkrun d="$d" m="$m" y="$y" 'BEGIN { printf "%02i/%02i/%04i\n", d, m, y }'
|
||
;;
|
||
l|ldap)
|
||
awkrun d="$d" m="$m" y="$y" 'BEGIN { printf "%04i%02i%02i000000+0400\n", y, m, d }'
|
||
;;
|
||
esac
|
||
}
|
||
function myhost() {
|
||
hostname
|
||
}
|
||
function myhostname() {
|
||
hostname -s
|
||
}
|
||
fi
|
||
##@inc]compat
|
||
##@inc[crontab
|
||
## Gestion du fichier crontab
|
||
##@require base
|
||
uprovide crontab
|
||
urequire base
|
||
|
||
function add_to_crontab() {
|
||
local -a crontab=(crontab ${2:+-u "$2"})
|
||
local current="$("${crontab[@]}" -l 2>/dev/null)"
|
||
local tmpfile
|
||
ac_set_tmpfile tmpfile
|
||
if [ -n "$current" ]; then
|
||
echo "$current" >"$tmpfile"
|
||
fi
|
||
local NL=$'\n'
|
||
if quietgrep -xF "$1$NL#$1" "$tmpfile"; then
|
||
ac_clean "$tmpfile"
|
||
return 123
|
||
else
|
||
echo "$1" >>"$tmpfile"
|
||
"${crontab[@]}" "$tmpfile"
|
||
ac_clean "$tmpfile"
|
||
fi
|
||
}
|
||
function remove_from_crontab() {
|
||
local -a crontab=(crontab ${2:+-u "$2"})
|
||
local current="$("${crontab[@]}" -l 2>/dev/null)"
|
||
local tmpfile
|
||
ac_set_tmpfile tmpfile
|
||
if [ -n "$current" ]; then
|
||
echo "$current" >"$tmpfile"
|
||
fi
|
||
local NL=$'\n'
|
||
if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
|
||
ac_clean "$tmpfile"
|
||
return 123
|
||
else
|
||
grep -vxF "$1$NL#$1" "$tmpfile" | "${crontab[@]}" -
|
||
ac_clean "$tmpfile"
|
||
fi
|
||
}
|
||
function disable_in_crontab() {
|
||
local -a crontab=(crontab ${2:+-u "$2"})
|
||
local current="$("${crontab[@]}" -l 2>/dev/null)"
|
||
local tmpfile
|
||
ac_set_tmpfile tmpfile
|
||
if [ -n "$current" ]; then
|
||
echo "$current" >"$tmpfile"
|
||
fi
|
||
local NL=$'\n'
|
||
if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
|
||
echo "#$1" >>"$tmpfile"
|
||
"${crontab[@]}" "$tmpfile"
|
||
elif quietgrep -xF "#$1" "$tmpfile"; then
|
||
ac_clean "$tmpfile"
|
||
return 123
|
||
else
|
||
<"$tmpfile" awkrun line="$1" '$0 == line { $0 = "#" $0 } { print }' | "${crontab[@]}" -
|
||
ac_clean "$tmpfile"
|
||
fi
|
||
}
|
||
function enable_in_crontab() {
|
||
local -a crontab=(crontab ${2:+-u "$2"})
|
||
local current="$("${crontab[@]}" -l 2>/dev/null)"
|
||
local tmpfile
|
||
ac_set_tmpfile tmpfile
|
||
if [ -n "$current" ]; then
|
||
echo "$current" >"$tmpfile"
|
||
fi
|
||
local NL=$'\n'
|
||
if ! quietgrep -xF "$1$NL#$1" "$tmpfile"; then
|
||
echo "$1" >>"$tmpfile"
|
||
"${crontab[@]}" "$tmpfile"
|
||
elif quietgrep -xF "$1" "$tmpfile"; then
|
||
ac_clean "$tmpfile"
|
||
return 123
|
||
else
|
||
<"$tmpfile" awkrun line="$1" '$0 == "#" line { sub(/^#/, "") } { print }' | "${crontab[@]}" -
|
||
ac_clean "$tmpfile"
|
||
fi
|
||
}
|
||
function ctnow() {
|
||
date +"%-M %-H %-d %-m %u"
|
||
}
|
||
__CTRESOLVE_CTNOW=""
|
||
function ctresolve() {
|
||
local -a ctnow
|
||
if [ -n "$__CTRESOLVE_CTNOW" ]; then
|
||
eval "ctnow=($__CTRESOLVE_CTNOW)"
|
||
else
|
||
eval "ctnow=($(ctnow))"
|
||
fi
|
||
filter_conf | awkrun -f ctnow[@] '
|
||
function ctmatch_one(ctval, ref, parts, part, i, j, start, end, step, ok) {
|
||
ok = 0
|
||
split(ctval, parts, /,/)
|
||
for(i = 1; i <= length(parts); i++) {
|
||
part = parts[i]
|
||
start = -1; end = -1; step = 1
|
||
pos = index(part, "/")
|
||
if (pos != 0) {
|
||
step = substr(part, pos + 1) + 0
|
||
part = substr(part, 1, pos - 1)
|
||
}
|
||
pos = index(part, "-")
|
||
if (pos != 0) {
|
||
start = substr(part, 1, pos - 1) + 0
|
||
end = substr(part, pos + 1) + 0
|
||
} else {
|
||
start = part + 0
|
||
end = start
|
||
}
|
||
for (j = start; j <= end; j += step) {
|
||
if (j == ref) {
|
||
ok = 1
|
||
break
|
||
}
|
||
}
|
||
if (ok) break
|
||
}
|
||
return ok
|
||
}
|
||
function ctmatch_all(M, H, dom, mon, dow, refM, refH, refdom, refmon, refdow, Mok, Hok, domok, monok, dowok) {
|
||
gsub(/\*/, "0-59", M)
|
||
Mok = ctmatch_one(M, refM)
|
||
|
||
gsub(/\*/, "0-23", H)
|
||
Hok = ctmatch_one(H, refH)
|
||
|
||
gsub(/\*/, "1-31", dom)
|
||
domok = ctmatch_one(dom, refdom)
|
||
|
||
gsub(/\*/, "1-12", mon)
|
||
monok = ctmatch_one(mon, refmon)
|
||
|
||
gsub(/\*/, "1-7", dow)
|
||
dowok = ctmatch_one(dow, refdow)
|
||
|
||
return Mok && Hok && monok && (domok || dowok)
|
||
}
|
||
function print_cmd(cmd) {
|
||
print "__ctexec " quote_value(cmd)
|
||
}
|
||
|
||
BEGIN {
|
||
refM = ctnow[1]; refH = ctnow[2]; refdom = ctnow[3]; refmon = ctnow[4]; refdow = ctnow[5]
|
||
ctref = refM " " refH " " refdom " " refmon " " refdow
|
||
print "## now: " ctref
|
||
|
||
ctline_run = 0
|
||
ctline_run_one_match = 0
|
||
match_indented = 0
|
||
}
|
||
|
||
/^(export[ \t]+)?[a-zA-Z_][a-zA-Z0-9_]*[-+%#?]=/ {
|
||
ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
|
||
|
||
match($0, /^(export[ \t]+)?([a-zA-Z_][a-zA-Z0-9_]*)([-+%#?])=(.*)$/, parts)
|
||
name = parts[2]
|
||
type = parts[3]
|
||
value = parts[4]
|
||
if (type == "+" || type == "%") {
|
||
print "uaddpath " value " " name
|
||
} else if (type == "#") {
|
||
print "uinspath " value " " name
|
||
} else if (type == "-") {
|
||
print "udelpath " value " " name
|
||
} else if (type == "?") {
|
||
print "[ -n \"$" name "\" ] || " name "=" value
|
||
}
|
||
print "export " name
|
||
next
|
||
}
|
||
/^(export[ \t]+)?[a-zA-Z_][a-zA-Z0-9_]*=/ {
|
||
ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
|
||
|
||
sub(/^export[ \t]+/, "", $0)
|
||
print "export " $0
|
||
next
|
||
}
|
||
/^\$.+/ {
|
||
ctline_run = 0; ctline_run_one_match = 0; match_indented = 0
|
||
|
||
if ($0 ~ /^\$\{([ \t]*(#.*)?)?$/) {
|
||
getline
|
||
while ($0 !~ /^\$\}([ \t]*(#.*)?)?$/) {
|
||
print
|
||
if (getline <= 0) break
|
||
}
|
||
} else {
|
||
sub(/^\$/, "", $0)
|
||
print
|
||
}
|
||
next
|
||
}
|
||
|
||
/^[ \t]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+[ ]*[-0-9/*,]+/ {
|
||
match_indented = 0
|
||
|
||
M = $1; H = $2; dom = $3; mon = $4; dow = $5
|
||
ctline = M " " H " " dom " " mon " " dow
|
||
|
||
sub(/^[ \t]*[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]+[^ ]+[ ]*/, "", $0)
|
||
cmd = $0
|
||
|
||
match_cur = ctmatch_all(M, H, dom, mon, dow, refM, refH, refdom, refmon, refdow)
|
||
if (match_cur) print "## match: " ctline
|
||
|
||
if (cmd == "") {
|
||
ctline_run = 1
|
||
if (match_cur) ctline_run_one_match = 1
|
||
if (ctline_run_one_match) match_indented = 1
|
||
|
||
} else {
|
||
if (ctline_run && match_cur) ctline_run_one_match = 1
|
||
if (ctline_run && ctline_run_one_match) {
|
||
print_cmd(cmd)
|
||
match_indented = 1
|
||
}
|
||
|
||
if (!ctline_run && match_cur) {
|
||
print_cmd(cmd)
|
||
match_indented = 1
|
||
}
|
||
|
||
ctline_run = 0
|
||
ctline_run_one_match = 0
|
||
}
|
||
|
||
next
|
||
}
|
||
/^[ \t]+/ {
|
||
ctline_run = 0; ctline_run_one_match = 0
|
||
|
||
if (match_indented) {
|
||
sub(/^[ \t]+/, "", $0)
|
||
print_cmd($0)
|
||
}
|
||
|
||
next
|
||
}
|
||
{
|
||
print "__cterror " quote_value("ligne de format incorrect: " $0)
|
||
}
|
||
'
|
||
}
|
||
|
||
|
||
function get_default_crontabdir_prefix() {
|
||
if check_sysinfos -s darwin; then
|
||
if check_sysinfos -d 10.6+; then
|
||
echo /var/at/tabs
|
||
else
|
||
echo /var/cron/tabs
|
||
fi
|
||
elif check_sysinfos -s linux; then
|
||
if check_sysinfos -d debianlike; then
|
||
echo /var/spool/cron/crontabs
|
||
elif check_sysinfos -d redhatlike; then
|
||
echo /var/spool/cron
|
||
fi
|
||
fi
|
||
}
|
||
|
||
__crontab_prefixes=
|
||
function __compute_crontab_prefixes() {
|
||
[ -n "$__crontab_prefixes" ] && return
|
||
CRONTABDIR="${CRONTABDIR:-$(get_default_crontabdir_prefix)}"
|
||
__crontab_prefixes=1
|
||
}
|
||
|
||
UTOOLS_PREFIXES=("${UTOOLS_PREFIXES[@]}" CRONTABDIR)
|
||
|
||
function compute_crontab_prefixes() {
|
||
__compute_crontab_prefixes
|
||
}
|
||
|
||
function recompute_crontab_prefixes() {
|
||
__crontab_prefixes=
|
||
__compute_crontab_prefixes
|
||
}
|
||
|
||
function get_CRONTABDIR_prefix() {
|
||
__compute_crontab_prefixes
|
||
echo "$CRONTABDIR"
|
||
}
|
||
##@inc]crontab
|
||
|
||
action=add_to_crontab
|
||
actionopt=-a
|
||
user=root
|
||
hosts=()
|
||
ctline=
|
||
time=
|
||
dom=
|
||
month=
|
||
cmdfile=
|
||
cmd=
|
||
hostsfiles=()
|
||
increment=auto
|
||
adelay="$DEFAULT_ADELAY"
|
||
undoscript=
|
||
dundoscript=1
|
||
fake=
|
||
autoclean=
|
||
parse_opts "${PRETTYOPTS[@]}" \
|
||
--help '$exit_with display_help' \
|
||
-a '$action=add_to_crontab; actionopt=-a' \
|
||
-r '$action=remove_from_crontab; actionopt=-r' \
|
||
-u: user= \
|
||
-h:,-H: hosts \
|
||
-t: time= \
|
||
--dom: dom= \
|
||
--month: month= \
|
||
-s: cmdfile= \
|
||
-S: cmd= \
|
||
-f: hostsfiles \
|
||
-d increment=1 \
|
||
-n increment= \
|
||
--add: adelay= \
|
||
--us: '$set@ undoscript; dundoscript=' \
|
||
--fake fake=1 \
|
||
--autoclean: autoclean= \
|
||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||
|
||
array_fix_paths hosts
|
||
if [ "$action" != "add_to_crontab" ]; then
|
||
# undoscript n'est valide que pour l'action -a
|
||
undoscript=
|
||
fi
|
||
if [ -n "$cmdfile" -a -z "$cmd" ]; then
|
||
cmd="$(<"$cmdfile")" || die
|
||
fi
|
||
[ -n "$cmdfile" ] && cmdfile="$(basename "$cmdfile")"
|
||
if [ -n "$dundoscript" -a "$action" == "add_to_crontab" ]; then
|
||
if [ -n "${hosts[*]}" -o -n "${hostsfiles[*]}" ]; then
|
||
# par défaut, faire un script d'annulation pour les déploiements
|
||
# distants
|
||
undoscript="undo-ucrontab.sh"
|
||
fi
|
||
fi
|
||
|
||
################################################################################
|
||
# Fonctions
|
||
|
||
function update_undoscript() {
|
||
# Mettre à jour le fichier d'annulation $1 pour enlever la ligne de crontab
|
||
# $4 en se connectant éventuellement sur l'hôte $3 avec le user $2
|
||
local undoscript="$1" user="$2" host="$3" ctline="$4"
|
||
|
||
# $undoscript doit être défini
|
||
[ -n "$undoscript" ] || return
|
||
[ -n "$fake" ] && undoscript="fake-$undoscript"
|
||
|
||
[ -z "$fake" ] && estep "Maj de $undoscript"
|
||
if [ ! -f "$undoscript" ]; then
|
||
cat >"$undoscript" <<EOF
|
||
#!/bin/bash
|
||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||
allok=1
|
||
function __autoclean() { [ -n "\$allok" ] && /bin/rm -f "\$0"; }
|
||
trap __autoclean 1 3 15 EXIT
|
||
|
||
EOF
|
||
chmod +x "$undoscript"
|
||
fi
|
||
|
||
local -a undocmd
|
||
undocmd=("$script" -r -u "$user")
|
||
[ -n "$undocmd" ] && {
|
||
undocmd=("${undocmd[@]}" -s "$cmdfile" -S "")
|
||
[ -n "$cmdfile" ] && ctline="$(update_cmd "$ctline" "$cmdfile")"
|
||
}
|
||
[ -n "$host" ] && undocmd=("${undocmd[@]}" -H "$host")
|
||
undocmd=("${undocmd[@]}" "$ctline")
|
||
echo "$(quoted_args "${undocmd[@]}") || allok=" >>"$undoscript"
|
||
}
|
||
|
||
function get_time() {
|
||
# obtenir l'heure sous la forme hh:mm correspondant à la ligne de crontab
|
||
# $1.
|
||
awk '{print $2 ":" $1 }' <<<"$1"
|
||
}
|
||
|
||
function update_time() {
|
||
# Ajouter $2 minutes à l'heure $1, de la forme hh:mm
|
||
local time="$1" offset="$2"
|
||
local hours minutes
|
||
|
||
time="${time//./:}"
|
||
if [[ "$time" == *:* ]]; then
|
||
hours="${time%%:*}"
|
||
minutes="${time#*:}"
|
||
else
|
||
hours="$time"
|
||
minutes=0
|
||
fi
|
||
hours="${hours:-7}"
|
||
minutes="${minutes:-0}"
|
||
|
||
if [ -n "$offset" ]; then
|
||
hours=$(($hours * 60 + $minutes + $offset))
|
||
minutes=$(($hours % 60))
|
||
hours=$(($hours / 60))
|
||
# XXX le cas où hours >= 24 n'est pas traité
|
||
fi
|
||
|
||
echo "$hours:$minutes"
|
||
}
|
||
|
||
function update_ctline() {
|
||
# Mettre à jour la ligne de crontab $1 avec l'heure $2 à laquelle on rajoute
|
||
# $3 minutes
|
||
local ctline="$1" time="$2" offset="$3"
|
||
local hours minutes
|
||
|
||
time="$(update_time "$time" "$offset")"
|
||
splitpair "$time" hours minutes
|
||
|
||
awkrun minutes="$minutes" hours="$hours" dom="$dom" month="$month" '{$1=minutes; $2=hours; $3=dom; $4=month; $5="*"; print}' <<<"$ctline"
|
||
}
|
||
|
||
function update_cmd() {
|
||
# Mettre à jour la ligne de crontab $1 avec la commande $2
|
||
local ctline="$1" cmd="$2"
|
||
awkrun cmd="$cmd" '{$0 = $1 " " $2 " " $3 " " $4 " " $5 " " cmd; print}' <<<"$ctline"
|
||
}
|
||
|
||
|
||
################################################################################
|
||
# Programme principal
|
||
|
||
function do_local() {
|
||
if [ "$user" != "root" -a "$user" == "$USER" ]; then
|
||
# Si le user n'est pas root, et qu'il s'agisse du user courant, il ne faut
|
||
# pas utiliser l'option -u de crontab
|
||
user=
|
||
fi
|
||
[ -n "$cmdfile" ] || cmdfile=custom-script
|
||
|
||
local r=0
|
||
local tmpcmd="$TMPDIR/ucrontab-$(basename "$cmdfile")"
|
||
if [ -n "$cmd" ]; then
|
||
echo "\
|
||
#!/bin/bash
|
||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||
$cmd"'
|
||
/bin/rm -f "$0"; exit 0' >"$tmpcmd"
|
||
chmod +x "$tmpcmd"
|
||
ctline="$(update_cmd "$ctline" "$tmpcmd")"
|
||
fi
|
||
|
||
if [ -n "$fake" ]; then
|
||
if [ -n "$cmd" ]; then
|
||
eecho "$action $(quoted_args "$(update_cmd "$ctline" "$tmpcmd:")")
|
||
$(sed 's/^/ /g' <<<"$cmd")"
|
||
else
|
||
eecho "$action $(quoted_args "$ctline")"
|
||
fi
|
||
elif "$action" "$ctline" "$user"; then
|
||
estep "$action $ctline"
|
||
update_undoscript "$undoscript" "$user" "" "$ctline"
|
||
else
|
||
r=$?
|
||
if [ $r -eq 123 ]; then
|
||
# ignorer les erreurs si la ligne a déjà été ajoutée/supprimée
|
||
r=0
|
||
if [ "$action" == "add_to_crontab" ]; then
|
||
ewarn "La ligne '$ctline' existe déjà dans crontab"
|
||
elif [ "$action" == "remove_from_crontab" ]; then
|
||
ewarn "La ligne '$ctline' a déjà été supprimée de crontab"
|
||
fi
|
||
else
|
||
eerror "Une erreur s'est produite"
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$autoclean" ]; then
|
||
if [ "$autoclean" == "$scriptname" ]; then
|
||
[ -z "$fake" ] && autoclean "$script"
|
||
else
|
||
eerror "Invalid autoclean option"
|
||
fi
|
||
fi
|
||
|
||
return $r
|
||
}
|
||
|
||
function do_remote() {
|
||
local r=0
|
||
[ -n "$cmd" -a -z "$cmdfile" ] && cmdfile=custom-script
|
||
for host in "${hosts[@]}"; do
|
||
if [ "$host" == "." -o "$host" == "localhost" ]; then
|
||
do_local
|
||
continue
|
||
fi
|
||
|
||
if [[ "$host" == *@* ]]; then
|
||
ssh_user="${host%%@*}"
|
||
host="${host#*@}"
|
||
else
|
||
ssh_user="$user"
|
||
fi
|
||
ssh_cmd="$(quoted_args chmod +x "$remotename"); $(quoted_args "./$remotename" --autoclean "$remotename" "$actionopt" -u "$user" --dom "$dom" --month "$month" ${cmd:+-s "$cmdfile" -S "$cmd"} "$ctline"); true"
|
||
|
||
[ -z "$fake" ] && etitle -s "$host"
|
||
ok=
|
||
if [ -n "$fake" ]; then
|
||
if [ -n "$cmd" ]; then
|
||
eecho "[$host] $action $(quoted_arg "$(update_cmd "$ctline" "$cmdfile:")")
|
||
$(sed 's/^/ /g' <<<"$cmd")"
|
||
else
|
||
eecho "[$host] $action $(quoted_arg "$ctline")"
|
||
fi
|
||
ok=1
|
||
elif scp -o ConnectTimeout=5 -q "$script" "$ssh_user@$host:$remotename"; then
|
||
if ssh -o ConnectTimeout=5 -qt "$ssh_user@$host" "$ssh_cmd"; then
|
||
ok=1
|
||
else
|
||
r=$?
|
||
fi
|
||
else
|
||
r=$?
|
||
fi
|
||
if [ -n "$ok" ]; then
|
||
update_undoscript "$undoscript" "$user" "$ssh_user@$host" "$ctline"
|
||
if [ -n "$increment" ]; then
|
||
aoffset=$(($aoffset + $adelay))
|
||
ctline="$(update_ctline "$ctline" "$time" "$aoffset")"
|
||
fi
|
||
else
|
||
eerror "Une erreur s'est produite. Cet hôte a été ignoré"
|
||
fi
|
||
[ -z "$fake" ] && eend
|
||
done
|
||
return $r
|
||
}
|
||
|
||
# calculer dom si nécessaire
|
||
if [ -z "$dom" -o -z "$month" ]; then
|
||
tomorrow="$(parse_date +1)"
|
||
[ -n "$dom" ] || dom="${tomorrow%%/*}"
|
||
[ -n "$month" ] || { month="${tomorrow#*/}"; month="${month%/*}"; }
|
||
fi
|
||
DEFAULT_CTLINE="0 7 $dom $month * /sbin/shutdown -h now"
|
||
# obtenir et mettre à jour si nécessaire ctline
|
||
ctline="$1"
|
||
if [ "${ctline#halt}" != "$ctline" ]; then
|
||
if [ "${ctline#halt@}" != "$ctline" ]; then
|
||
time="${ctline#halt@}"
|
||
fi
|
||
ctline="$DEFAULT_CTLINE"
|
||
[ "$increment" == "auto" ] && increment=1
|
||
fi
|
||
if [ -n "$hostsfiles" ]; then
|
||
# il faudra traiter un fichier d'hôtes
|
||
[ -n "$ctline" ] || ctline="$DEFAULT_CTLINE"
|
||
else
|
||
# il faudra traiter l'hote local ou les hôtes spécifiés sur la ligne de
|
||
# commande
|
||
[ -n "$ctline" ] || die "Vous devez spécifier la ligne de crontab"
|
||
fi
|
||
[ -n "$time" ] && ctline="$(update_ctline "$ctline" "$time")"
|
||
[ -z "$time" ] && time="$(get_time "$ctline")"
|
||
# par défaut, ne pas auto-incrémenter
|
||
[ "$increment" == "auto" ] && increment=
|
||
# pour la configuration remote
|
||
remotename="$scriptname.$$"
|
||
aoffset=0
|
||
|
||
if [ -n "$hostsfiles" ]; then
|
||
# traiter un fichier d'hôtes
|
||
orig_ctline="$ctline"
|
||
orig_cmdfile="$cmdfile"
|
||
orig_cmd="$cmd"
|
||
increment= # incrémentation spécifique dans cette section
|
||
|
||
first_host=1
|
||
adelay="${adelay:-$DEFAULT_ADELAY}"
|
||
gdelay=
|
||
function start_group() {
|
||
if [ -n "$gdelay" ]; then
|
||
# maj de time avec la nouvelle valeur
|
||
time="$(update_time "$time" $(($aoffset + $gdelay)))"
|
||
fi
|
||
adelay="${1:-$DEFAULT_ADELAY}"
|
||
gdelay="${2:-$DEFAULT_GDELAY}"
|
||
aoffset=0
|
||
first_host=1
|
||
}
|
||
function do_host() {
|
||
hosts=("$1")
|
||
ctline="$orig_ctline"
|
||
cmdfile="$orig_cmdfile"
|
||
cmd="$orig_cmd"
|
||
if [ -n "$2" ]; then
|
||
if [ "${2#<}" != "$2" ]; then
|
||
# on a spécifié un fichier de script
|
||
cmdfile="${2#<}"
|
||
cmd="$(<"$cmdfile")" || return 1
|
||
else
|
||
# utiliser directement cette commande
|
||
cmdfile=
|
||
cmd=
|
||
ctline="$(update_cmd "$ctline" "$2")"
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$first_host" ]; then
|
||
first_host=
|
||
else
|
||
aoffset=$(($aoffset + $adelay))
|
||
fi
|
||
ctline="$(update_ctline "$ctline" "$time" "$aoffset")"
|
||
do_remote
|
||
}
|
||
appended_hostsfiles=()
|
||
function do_include() {
|
||
array_add appended_hostsfiles "$1"
|
||
}
|
||
|
||
r=0
|
||
while [ -n "${appended_hostsfiles[*]}" -o -n "${hostsfiles[*]}" ]; do
|
||
for hostsfile in "${hostsfiles[@]}"; do
|
||
[ -f "$hostsfile" ] || die "$hostsfile: fichier introuvable"
|
||
eval "$(<"$hostsfile" filter_conf -m | awkrun -f FS=: '
|
||
$1 == "@group" {
|
||
adelay = $2
|
||
gdelay = $3
|
||
print "start_group " quote_value(adelay) " " quote_value(gdelay)
|
||
next
|
||
}
|
||
$1 == "@include" {
|
||
append = $2
|
||
print "do_include " quote_value(append)
|
||
next
|
||
}
|
||
{
|
||
host = $1
|
||
cmd = $2
|
||
print "do_host " quote_value(host) " " quote_value(cmd)
|
||
}
|
||
')" || r=$?
|
||
done
|
||
hostsfiles=("${appended_hostsfiles[@]}")
|
||
appended_hostsfiles=()
|
||
done
|
||
exit $r
|
||
|
||
else
|
||
# traiter l'hote local ou les hôtes spécifiés sur la ligne de commande
|
||
if [ -n "${hosts[*]}" ]; then
|
||
do_remote; exit $?
|
||
else
|
||
do_local; exit $?
|
||
fi
|
||
fi
|