nutools/ucrontab

9141 lines
250 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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
uprovide base.init
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/debian_chroot ] && UTOOLS_CHROOT=1
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
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
##@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
local first="${1:1}"; shift
echo -n -
echo "$first" "$@"
else
echo "$@"
fi
}
function recho_() {
if [[ "${1:0:2}" == -[eEn] ]]; then
local first="${1:1}"; shift
echo -n -
echo -n "$first" "$@"
else
echo -n "$@"
fi
}
function _qval() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function should_quote() {
local s="$*"
local l="${#s}"
[ $l -eq 0 -o $l -gt 80 ] && return 0
s="${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 qwc() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
local r a b c
while [ -n "$s" ]; do
a=; b=; c=
a=; [[ "$s" == *\** ]] && { a="${s%%\**}"; a=${#a}; }
b=; [[ "$s" == *\?* ]] && { b="${s%%\?*}"; b=${#b}; }
c=; [[ "$s" == *\[* ]] && { c="${s%%\[*}"; c=${#c}; }
if [ -z "$a" -a -z "$b" -a -z "$c" ]; then
r="$r\"$s\""
break
fi
if [ -n "$a" ]; then
[ -n "$b" ] && [ $a -lt $b ] && b=
[ -n "$c" ] && [ $a -lt $c ] && c=
fi
if [ -n "$b" ]; then
[ -n "$a" ] && [ $b -lt $a ] && a=
[ -n "$c" ] && [ $b -lt $c ] && c=
fi
if [ -n "$c" ]; then
[ -n "$a" ] && [ $c -lt $a ] && a=
[ -n "$b" ] && [ $c -lt $b ] && b=
fi
if [ -n "$a" ]; then # PREFIX*
a="${s%%\**}"
s="${s#*\*}"
[ -n "$a" ] && r="$r\"$a\""
r="$r*"
elif [ -n "$b" ]; then # PREFIX?
a="${s%%\?*}"
s="${s#*\?}"
[ -n "$a" ] && r="$r\"$a\""
r="$r?"
elif [ -n "$c" ]; then # PREFIX[class]
a="${s%%\[*}"
b="${s#*\[}"; b="${b%%\]*}"
s="${s:$((${#a} + ${#b} + 2))}"
[ -n "$a" ] && r="$r\"$a\""
r="$r[$b]"
fi
done
recho_ "$r"
}
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=\"\$*\""
}
function _setv() {
local __s_var="$1"; shift
eval "$__s_var=\"\$*\""
}
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 echo_setv2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
if [ $# -eq 0 ]; then
echo_setv "$__s_var" "${!__s_var}"
else
echo_setv "$__s_var" "$@"
fi
}
function seta() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=(\"\$@\")"
}
function _seta() {
local __s_array="$1"; shift
eval "$__s_array=(\"\$@\")"
}
function echo_seta() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
echo "$__s_var=($(qvals "$@"))"
}
function echo_seta2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
elif [ $# -eq 0 ]; then
eval "set -- \"\${$__s_var[@]}\""
fi
echo "$__s_var=($(qvals "$@"))"
}
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
}
function is_defined() {
[ -n "$(declare -p "$1" 2>/dev/null)" ]
}
function is_array() {
case "$(declare -p "$1" 2>/dev/null)" in declare\ -a*) return 0;; esac
return 1
}
function upvar() {
if unset -v "$1"; then
if [ $# -eq 2 ]; then
eval "$1=\"\$2\""
else
eval "$1=(\"\${@:2}\")"
fi
fi
}
function array_upvar() {
unset -v "$1" && eval "$1=(\"\${@:2}\")"
}
function upvars() {
while [ $# -gt 0 ]; do
case "$1" in
-a)
unset -v "$2" && eval "$2=(\"\${@:3}\")"
break
;;
-a*)
unset -v "$2" && eval "$2=(\"\${@:3:${1#-a}}\")"
shift $((${1#-a} + 2)) || return 1
;;
*)
unset -v "$1" && eval "$1=\"\$2\""
shift; shift
;;
esac
done
}
function __ab_process_pending() {
local -a values
case "$mode" in
cmd) values="$("${pending[@]}")";;
ssplit) eval "values=($("${pending[@]}"))";;
lsplit) eval "values=($("${pending[@]}" | qlines))";;
add) values=("${pending[@]}");;
esac
cmd=("${cmd[@]}" "${values[@]}")
pending=()
}
function array_buildcmd() {
local desta="$1"; shift; local "$desta"
local mode=add
local -a pending cmd
while [ $# -gt 0 ]; do
case "$1" in
++c|++cmd|++) __ab_process_pending; mode=cmd;;
++s|++ssplit) __ab_process_pending; mode=ssplit;;
++l|++lsplit) __ab_process_pending; mode=lsplit;;
++a|++add) __ab_process_pending; mode=add;;
*) pending=("${pending[@]}" "$1");;
esac
shift
done
__ab_process_pending
array_upvar "$desta" "${cmd[@]}"
}
function buildcmd() {
local -a args
array_buildcmd args "$@"
qvals "${args[@]}"
}
function evalcmd() {
local -a args
array_buildcmd args "$@"
"${args[@]}"
}
##@inc]base.core
##@inc[base.string
## Fonctions de base: gestion des valeurs chaines 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 strops() {
local -a __s_tmp
local __s_value="$1"; shift
while [ $# -gt 0 ]; do
case "$1" in
:-*|:=*|:\?*|:+*) eval '__s_value="${'"${__s_value}$1"'}"';;
d|deref) __s_value="${!__s_value}";;
dc|dcount|ds|dsize)
__s_value="${__s_value}[@]"
__s_tmp=("${!__s_value}")
__s_value="${#__s_tmp[@]}"
;;
\#*|%*|/*|:*|^*|,*) eval '__s_value="${__s_value'"$1"'}"';;
l|length) __s_value="${#__s_value}";;
=|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge)
__s_tmp=(\[ "$__s_value" "$@" ]); "${__s_tmp[@]}"; return $?;;
-n|-z) __s_tmp=(\[ "$1" "$__s_value" ]); "${__s_tmp[@]}"; return $?;;
+#*) eval '__s_value="'"${1#+#}"'$__s_value"';;
-#*) eval '__s_value="${__s_value'"${1#-}"'}"';;
+%*) eval '__s_value="$__s_value"'"${1#+%}";;
+*) eval '__s_value="$__s_value"'"${1#+}";;
-%*) eval '__s_value="${__s_value'"${1#-}"'}"';;
-*) eval '__s_value="${__s_value%'"${1#-}"'}"';;
mid|strmid) eval '__s_value="$(strmid "$2" "$__s_value")"'; shift;;
repl|strrepl) eval '__s_value="$(strrepl "$2" "$3" "$__s_value")"'; shift; shift;;
*) echo 1>&2 "strops: unknown operator: $1";;
esac
shift
done
echo "$__s_value"
}
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" ]'
}
function strsplitf() {
[ $# -gt 0 ] || return 127
local func count
func="$1"; shift
count=$#
if [ $count -gt 0 ]; then
eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126
fi
"$func" "$@"
}
function strecho() { recho "$@"; }
function strqvals() {
qvals "$@"
}
function strqlines() {
local -a lines
_setax lines cat "$@"
qvals "${lines[@]}"
}
function strqarray() {
local __a __s="qvals"
for __a in "$@"; do __s="$__s \"\${$__a[@]}\""; done
eval "$__s"
}
function evals() {
local __e_val __e_arg __e_r=0
local __e_firstcmd __e_firstarg __e_splitf
local -a __e_cmd
__e_firstcmd=1
while [ $# -gt 0 ]; do
__e_cmd=()
__e_firstarg=1 # premier argument
__e_splitf= # premier argument après splitf
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
if [ -n "$__e_firstarg" ]; then
__e_cmd=("str$__e_arg")
__e_firstarg=
[ "$__e_arg" == "splitf" ] && __e_splitf=1
elif [ -n "$__e_splitf" ]; then
__e_cmd=("${__e_cmd[@]}" "str$__e_arg")
__e_splitf=
else
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
fi
done
if [ -n "$__e_firstcmd" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_firstcmd=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
##@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} -gt 0 ] || return 1
v="${v//[0-9]/}"
[ -z "$v" ]
}
function ispnum() {
[ ${#1} -gt 0 ] || return 1
[ -z "${1//[0-9]/}" ]
}
function isrnum() {
[ ${#1} -gt 0 ] || return 1
local v="${1#-}"
[ ${#v} -gt 0 ] || return 1
v="${v//./}"
v="${v//,/}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function evali() {
echo "$(($*))"
}
##@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} -gt 0 ] || return 1
v="${v//[0-9]/}"
[ -z "$v" ]
}
function ispnum() {
[ ${#1} -gt 0 ] || return 1
[ -z "${1//[0-9]/}" ]
}
function isrnum() {
[ ${#1} -gt 0 ] || return 1
local v="${1#-}"
[ ${#v} -gt 0 ] || return 1
v="${v//./}"
v="${v//,/}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function evali() {
echo "$(($*))"
}
##@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 setyesval() {
is_yes "$2" && _setv "$1" 1 || _setv "$1" ""
}
function normyesval() {
is_yes "${2:-"${!1}"}" && _setv "$1" 1 || _setv "$1" ""
}
function normyesvals() {
local __nyv_yesvar
for __nyv_yesvar in "$@"; do
is_yes "${!__nyv_yesvar}" && _setv "$__nyv_yesvar" 1 || _setv "$__nyv_yesvar" ""
done
}
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//\//\\/}"
s="${s//
/\\n}"
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
}
function _qsql() {
local q="'" qq="''"
echo "${*//$q/$qq}"
}
function qsql() {
local q="'" qq="''"
echo "'${*//$q/$qq}'"
}
##@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 splitpath() {
splitlsep2 "$1" / "${2:-dir}" "${3:-name}"
}
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
local first="${1:1}"; shift
echo -n -
echo "$first" "$@"
else
echo "$@"
fi
}
function recho_() {
if [[ "${1:0:2}" == -[eEn] ]]; then
local first="${1:1}"; shift
echo -n -
echo -n "$first" "$@"
else
echo -n "$@"
fi
}
function _qval() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function should_quote() {
local s="$*"
local l="${#s}"
[ $l -eq 0 -o $l -gt 80 ] && return 0
s="${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 qwc() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
local r a b c
while [ -n "$s" ]; do
a=; b=; c=
a=; [[ "$s" == *\** ]] && { a="${s%%\**}"; a=${#a}; }
b=; [[ "$s" == *\?* ]] && { b="${s%%\?*}"; b=${#b}; }
c=; [[ "$s" == *\[* ]] && { c="${s%%\[*}"; c=${#c}; }
if [ -z "$a" -a -z "$b" -a -z "$c" ]; then
r="$r\"$s\""
break
fi
if [ -n "$a" ]; then
[ -n "$b" ] && [ $a -lt $b ] && b=
[ -n "$c" ] && [ $a -lt $c ] && c=
fi
if [ -n "$b" ]; then
[ -n "$a" ] && [ $b -lt $a ] && a=
[ -n "$c" ] && [ $b -lt $c ] && c=
fi
if [ -n "$c" ]; then
[ -n "$a" ] && [ $c -lt $a ] && a=
[ -n "$b" ] && [ $c -lt $b ] && b=
fi
if [ -n "$a" ]; then # PREFIX*
a="${s%%\**}"
s="${s#*\*}"
[ -n "$a" ] && r="$r\"$a\""
r="$r*"
elif [ -n "$b" ]; then # PREFIX?
a="${s%%\?*}"
s="${s#*\?}"
[ -n "$a" ] && r="$r\"$a\""
r="$r?"
elif [ -n "$c" ]; then # PREFIX[class]
a="${s%%\[*}"
b="${s#*\[}"; b="${b%%\]*}"
s="${s:$((${#a} + ${#b} + 2))}"
[ -n "$a" ] && r="$r\"$a\""
r="$r[$b]"
fi
done
recho_ "$r"
}
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=\"\$*\""
}
function _setv() {
local __s_var="$1"; shift
eval "$__s_var=\"\$*\""
}
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 echo_setv2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
if [ $# -eq 0 ]; then
echo_setv "$__s_var" "${!__s_var}"
else
echo_setv "$__s_var" "$@"
fi
}
function seta() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=(\"\$@\")"
}
function _seta() {
local __s_array="$1"; shift
eval "$__s_array=(\"\$@\")"
}
function echo_seta() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
echo "$__s_var=($(qvals "$@"))"
}
function echo_seta2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
elif [ $# -eq 0 ]; then
eval "set -- \"\${$__s_var[@]}\""
fi
echo "$__s_var=($(qvals "$@"))"
}
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
}
function is_defined() {
[ -n "$(declare -p "$1" 2>/dev/null)" ]
}
function is_array() {
case "$(declare -p "$1" 2>/dev/null)" in declare\ -a*) return 0;; esac
return 1
}
function upvar() {
if unset -v "$1"; then
if [ $# -eq 2 ]; then
eval "$1=\"\$2\""
else
eval "$1=(\"\${@:2}\")"
fi
fi
}
function array_upvar() {
unset -v "$1" && eval "$1=(\"\${@:2}\")"
}
function upvars() {
while [ $# -gt 0 ]; do
case "$1" in
-a)
unset -v "$2" && eval "$2=(\"\${@:3}\")"
break
;;
-a*)
unset -v "$2" && eval "$2=(\"\${@:3:${1#-a}}\")"
shift $((${1#-a} + 2)) || return 1
;;
*)
unset -v "$1" && eval "$1=\"\$2\""
shift; shift
;;
esac
done
}
function __ab_process_pending() {
local -a values
case "$mode" in
cmd) values="$("${pending[@]}")";;
ssplit) eval "values=($("${pending[@]}"))";;
lsplit) eval "values=($("${pending[@]}" | qlines))";;
add) values=("${pending[@]}");;
esac
cmd=("${cmd[@]}" "${values[@]}")
pending=()
}
function array_buildcmd() {
local desta="$1"; shift; local "$desta"
local mode=add
local -a pending cmd
while [ $# -gt 0 ]; do
case "$1" in
++c|++cmd|++) __ab_process_pending; mode=cmd;;
++s|++ssplit) __ab_process_pending; mode=ssplit;;
++l|++lsplit) __ab_process_pending; mode=lsplit;;
++a|++add) __ab_process_pending; mode=add;;
*) pending=("${pending[@]}" "$1");;
esac
shift
done
__ab_process_pending
array_upvar "$desta" "${cmd[@]}"
}
function buildcmd() {
local -a args
array_buildcmd args "$@"
qvals "${args[@]}"
}
function evalcmd() {
local -a args
array_buildcmd args "$@"
"${args[@]}"
}
##@inc]base.core
##@inc[base.string
## Fonctions de base: gestion des valeurs chaines 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 strops() {
local -a __s_tmp
local __s_value="$1"; shift
while [ $# -gt 0 ]; do
case "$1" in
:-*|:=*|:\?*|:+*) eval '__s_value="${'"${__s_value}$1"'}"';;
d|deref) __s_value="${!__s_value}";;
dc|dcount|ds|dsize)
__s_value="${__s_value}[@]"
__s_tmp=("${!__s_value}")
__s_value="${#__s_tmp[@]}"
;;
\#*|%*|/*|:*|^*|,*) eval '__s_value="${__s_value'"$1"'}"';;
l|length) __s_value="${#__s_value}";;
=|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge)
__s_tmp=(\[ "$__s_value" "$@" ]); "${__s_tmp[@]}"; return $?;;
-n|-z) __s_tmp=(\[ "$1" "$__s_value" ]); "${__s_tmp[@]}"; return $?;;
+#*) eval '__s_value="'"${1#+#}"'$__s_value"';;
-#*) eval '__s_value="${__s_value'"${1#-}"'}"';;
+%*) eval '__s_value="$__s_value"'"${1#+%}";;
+*) eval '__s_value="$__s_value"'"${1#+}";;
-%*) eval '__s_value="${__s_value'"${1#-}"'}"';;
-*) eval '__s_value="${__s_value%'"${1#-}"'}"';;
mid|strmid) eval '__s_value="$(strmid "$2" "$__s_value")"'; shift;;
repl|strrepl) eval '__s_value="$(strrepl "$2" "$3" "$__s_value")"'; shift; shift;;
*) echo 1>&2 "strops: unknown operator: $1";;
esac
shift
done
echo "$__s_value"
}
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" ]'
}
function strsplitf() {
[ $# -gt 0 ] || return 127
local func count
func="$1"; shift
count=$#
if [ $count -gt 0 ]; then
eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126
fi
"$func" "$@"
}
function strecho() { recho "$@"; }
function strqvals() {
qvals "$@"
}
function strqlines() {
local -a lines
_setax lines cat "$@"
qvals "${lines[@]}"
}
function strqarray() {
local __a __s="qvals"
for __a in "$@"; do __s="$__s \"\${$__a[@]}\""; done
eval "$__s"
}
function evals() {
local __e_val __e_arg __e_r=0
local __e_firstcmd __e_firstarg __e_splitf
local -a __e_cmd
__e_firstcmd=1
while [ $# -gt 0 ]; do
__e_cmd=()
__e_firstarg=1 # premier argument
__e_splitf= # premier argument après splitf
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
if [ -n "$__e_firstarg" ]; then
__e_cmd=("str$__e_arg")
__e_firstarg=
[ "$__e_arg" == "splitf" ] && __e_splitf=1
elif [ -n "$__e_splitf" ]; then
__e_cmd=("${__e_cmd[@]}" "str$__e_arg")
__e_splitf=
else
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
fi
done
if [ -n "$__e_firstcmd" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_firstcmd=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
##@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 "${2%%=*}="
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@ { setv "$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
setv "${name_%%=*}" "${name_#*=}"
else
inc@ "$name_"
fi
elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then
value_="$2"; shift
if [ "${name_%=}" != "$name_" ]; then
setv "${name_%=}" "$value_"
elif [[ "$name_" == *=* ]]; then
setv "${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() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_OPTS_SET_X=1; } # désactiver set -x pour cette fonction
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_" ] && setv "$destargs_" "$args_"
[ -n "$__ULIB_SET_X" ] && set -x
return 1
fi
[ -n "$__ULIB_PARSE_OPTS_SET_X" ] && set -x; return 0
}
function parse_args_check() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_ARGS_SET_X=1; } # désactiver set -x pour cette fonction
if parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@"; then
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x
return 0
else
eerror "$args"
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x
return 1
fi
}
function parse_args() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_ARGS_SET_X=1; } # désactiver set -x pour cette fonction
parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args"
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x; return 0
}
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 "$(echo_setv "$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.tools
## Fonctions de base: outils divers
##@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
local first="${1:1}"; shift
echo -n -
echo "$first" "$@"
else
echo "$@"
fi
}
function recho_() {
if [[ "${1:0:2}" == -[eEn] ]]; then
local first="${1:1}"; shift
echo -n -
echo -n "$first" "$@"
else
echo -n "$@"
fi
}
function _qval() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function should_quote() {
local s="$*"
local l="${#s}"
[ $l -eq 0 -o $l -gt 80 ] && return 0
s="${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 qwc() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
local r a b c
while [ -n "$s" ]; do
a=; b=; c=
a=; [[ "$s" == *\** ]] && { a="${s%%\**}"; a=${#a}; }
b=; [[ "$s" == *\?* ]] && { b="${s%%\?*}"; b=${#b}; }
c=; [[ "$s" == *\[* ]] && { c="${s%%\[*}"; c=${#c}; }
if [ -z "$a" -a -z "$b" -a -z "$c" ]; then
r="$r\"$s\""
break
fi
if [ -n "$a" ]; then
[ -n "$b" ] && [ $a -lt $b ] && b=
[ -n "$c" ] && [ $a -lt $c ] && c=
fi
if [ -n "$b" ]; then
[ -n "$a" ] && [ $b -lt $a ] && a=
[ -n "$c" ] && [ $b -lt $c ] && c=
fi
if [ -n "$c" ]; then
[ -n "$a" ] && [ $c -lt $a ] && a=
[ -n "$b" ] && [ $c -lt $b ] && b=
fi
if [ -n "$a" ]; then # PREFIX*
a="${s%%\**}"
s="${s#*\*}"
[ -n "$a" ] && r="$r\"$a\""
r="$r*"
elif [ -n "$b" ]; then # PREFIX?
a="${s%%\?*}"
s="${s#*\?}"
[ -n "$a" ] && r="$r\"$a\""
r="$r?"
elif [ -n "$c" ]; then # PREFIX[class]
a="${s%%\[*}"
b="${s#*\[}"; b="${b%%\]*}"
s="${s:$((${#a} + ${#b} + 2))}"
[ -n "$a" ] && r="$r\"$a\""
r="$r[$b]"
fi
done
recho_ "$r"
}
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=\"\$*\""
}
function _setv() {
local __s_var="$1"; shift
eval "$__s_var=\"\$*\""
}
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 echo_setv2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
if [ $# -eq 0 ]; then
echo_setv "$__s_var" "${!__s_var}"
else
echo_setv "$__s_var" "$@"
fi
}
function seta() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=(\"\$@\")"
}
function _seta() {
local __s_array="$1"; shift
eval "$__s_array=(\"\$@\")"
}
function echo_seta() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
echo "$__s_var=($(qvals "$@"))"
}
function echo_seta2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
elif [ $# -eq 0 ]; then
eval "set -- \"\${$__s_var[@]}\""
fi
echo "$__s_var=($(qvals "$@"))"
}
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
}
function is_defined() {
[ -n "$(declare -p "$1" 2>/dev/null)" ]
}
function is_array() {
case "$(declare -p "$1" 2>/dev/null)" in declare\ -a*) return 0;; esac
return 1
}
function upvar() {
if unset -v "$1"; then
if [ $# -eq 2 ]; then
eval "$1=\"\$2\""
else
eval "$1=(\"\${@:2}\")"
fi
fi
}
function array_upvar() {
unset -v "$1" && eval "$1=(\"\${@:2}\")"
}
function upvars() {
while [ $# -gt 0 ]; do
case "$1" in
-a)
unset -v "$2" && eval "$2=(\"\${@:3}\")"
break
;;
-a*)
unset -v "$2" && eval "$2=(\"\${@:3:${1#-a}}\")"
shift $((${1#-a} + 2)) || return 1
;;
*)
unset -v "$1" && eval "$1=\"\$2\""
shift; shift
;;
esac
done
}
function __ab_process_pending() {
local -a values
case "$mode" in
cmd) values="$("${pending[@]}")";;
ssplit) eval "values=($("${pending[@]}"))";;
lsplit) eval "values=($("${pending[@]}" | qlines))";;
add) values=("${pending[@]}");;
esac
cmd=("${cmd[@]}" "${values[@]}")
pending=()
}
function array_buildcmd() {
local desta="$1"; shift; local "$desta"
local mode=add
local -a pending cmd
while [ $# -gt 0 ]; do
case "$1" in
++c|++cmd|++) __ab_process_pending; mode=cmd;;
++s|++ssplit) __ab_process_pending; mode=ssplit;;
++l|++lsplit) __ab_process_pending; mode=lsplit;;
++a|++add) __ab_process_pending; mode=add;;
*) pending=("${pending[@]}" "$1");;
esac
shift
done
__ab_process_pending
array_upvar "$desta" "${cmd[@]}"
}
function buildcmd() {
local -a args
array_buildcmd args "$@"
qvals "${args[@]}"
}
function evalcmd() {
local -a args
array_buildcmd args "$@"
"${args[@]}"
}
##@inc]base.core
##@inc[base.string
## Fonctions de base: gestion des valeurs chaines 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 strops() {
local -a __s_tmp
local __s_value="$1"; shift
while [ $# -gt 0 ]; do
case "$1" in
:-*|:=*|:\?*|:+*) eval '__s_value="${'"${__s_value}$1"'}"';;
d|deref) __s_value="${!__s_value}";;
dc|dcount|ds|dsize)
__s_value="${__s_value}[@]"
__s_tmp=("${!__s_value}")
__s_value="${#__s_tmp[@]}"
;;
\#*|%*|/*|:*|^*|,*) eval '__s_value="${__s_value'"$1"'}"';;
l|length) __s_value="${#__s_value}";;
=|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge)
__s_tmp=(\[ "$__s_value" "$@" ]); "${__s_tmp[@]}"; return $?;;
-n|-z) __s_tmp=(\[ "$1" "$__s_value" ]); "${__s_tmp[@]}"; return $?;;
+#*) eval '__s_value="'"${1#+#}"'$__s_value"';;
-#*) eval '__s_value="${__s_value'"${1#-}"'}"';;
+%*) eval '__s_value="$__s_value"'"${1#+%}";;
+*) eval '__s_value="$__s_value"'"${1#+}";;
-%*) eval '__s_value="${__s_value'"${1#-}"'}"';;
-*) eval '__s_value="${__s_value%'"${1#-}"'}"';;
mid|strmid) eval '__s_value="$(strmid "$2" "$__s_value")"'; shift;;
repl|strrepl) eval '__s_value="$(strrepl "$2" "$3" "$__s_value")"'; shift; shift;;
*) echo 1>&2 "strops: unknown operator: $1";;
esac
shift
done
echo "$__s_value"
}
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" ]'
}
function strsplitf() {
[ $# -gt 0 ] || return 127
local func count
func="$1"; shift
count=$#
if [ $count -gt 0 ]; then
eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126
fi
"$func" "$@"
}
function strecho() { recho "$@"; }
function strqvals() {
qvals "$@"
}
function strqlines() {
local -a lines
_setax lines cat "$@"
qvals "${lines[@]}"
}
function strqarray() {
local __a __s="qvals"
for __a in "$@"; do __s="$__s \"\${$__a[@]}\""; done
eval "$__s"
}
function evals() {
local __e_val __e_arg __e_r=0
local __e_firstcmd __e_firstarg __e_splitf
local -a __e_cmd
__e_firstcmd=1
while [ $# -gt 0 ]; do
__e_cmd=()
__e_firstarg=1 # premier argument
__e_splitf= # premier argument après splitf
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
if [ -n "$__e_firstarg" ]; then
__e_cmd=("str$__e_arg")
__e_firstarg=
[ "$__e_arg" == "splitf" ] && __e_splitf=1
elif [ -n "$__e_splitf" ]; then
__e_cmd=("${__e_cmd[@]}" "str$__e_arg")
__e_splitf=
else
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
fi
done
if [ -n "$__e_firstcmd" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_firstcmd=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
##@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 "${2%%=*}="
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@ { setv "$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
setv "${name_%%=*}" "${name_#*=}"
else
inc@ "$name_"
fi
elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then
value_="$2"; shift
if [ "${name_%=}" != "$name_" ]; then
setv "${name_%=}" "$value_"
elif [[ "$name_" == *=* ]]; then
setv "${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() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_OPTS_SET_X=1; } # désactiver set -x pour cette fonction
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_" ] && setv "$destargs_" "$args_"
[ -n "$__ULIB_SET_X" ] && set -x
return 1
fi
[ -n "$__ULIB_PARSE_OPTS_SET_X" ] && set -x; return 0
}
function parse_args_check() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_ARGS_SET_X=1; } # désactiver set -x pour cette fonction
if parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@"; then
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x
return 0
else
eerror "$args"
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x
return 1
fi
}
function parse_args() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_PARSE_ARGS_SET_X=1; } # désactiver set -x pour cette fonction
parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args"
[ -n "$__ULIB_PARSE_ARGS_SET_X" ] && set -x; return 0
}
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 "$(echo_setv "$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
uprovide base.tools
urequire base.args #XXX il manque des dépendances!
function base_umove() {
local -a args
local updatedir
args=(-d:,--updatedir: .)
parse_args_check "$@" || return; set -- "${args[@]}"
eerror_unless [ -z "$updatedir" -o -d "$updatedir" ] "$updatedir: doit être un répertoire" || return
eerror_if [ $# -eq 0 ] "Vous devez spécifier les fichiers à déplacer" || return
eerror_if [ $# -eq 1 ] "Vous devez spécifier la destination" || return
local -a srcs
local src dest
srcs=("$@")
setx dest=last_value srcs
array_del_last srcs
if [ $# -eq 2 ]; then
if [ -d "$dest" ]; then
: # ce cas sera traité ci-dessous
elif [ -e "$dest" ]; then
eerror "$dest: refus d'écraser la destination"
return 1
else
src="${srcs[0]}"
if [ -n "$updatedir" ]; then
if [ -L "$src" ]; then
ldest="$(readlinka "$src")"
array_find_links update_links "$ldest" "$updatedir"
else
array_find_links update_links "$src" "$updatedir"
fi
move_file "$src" "$dest" "${update_links[@]}"
else
move_link "$src" "$dest"
fi
return $?
fi
fi
[ -d "$dest" ] || {
eerror "$dest: doit être un répertoire"
return 1
}
local r=0
for src in "${srcs[@]}"; do
if [ -n "$updatedir" ]; then
if [ -L "$src" ]; then
move_link "$src" "$dest" || r=$?
else
array_find_links update_links "$src" "$updatedir"
move_file "$src" "$dest" "${update_links[@]}" || r=$?
fi
else
move_link "$src" "$dest" || r=$?
fi
done
return $r
}
function base_udelete() {
local -a args
local updatedir
args=(-d:,--updatedir: .)
parse_args_check "$@" || return; set -- "${args[@]}"
eerror_unless [ -z "$updatedir" -o -d "$updatedir" ] "$updatedir: doit être un répertoire" || return
eerror_if [ $# -eq 0 ] "Vous devez spécifier les fichiers à supprimer" || return
local file r=0
for file in "$@"; do
if [ -n "$updatedir" ]; then
if [ -L "$file" ]; then
rm "$file" || r=$?
else
array_find_links update_links "$file" "$updatedir"
rm "$file" "${update_links[@]}" || r=$?
fi
else
rm "$file" || r=$?
fi
done
return $r
}
function base_ucopy() {
eerror_if [ $# -eq 0 ] "Vous devez spécifier les fichiers à copier" || return
eerror_if [ $# -eq 1 ] "Vous devez spécifier la destination" || return
local -a srcs
local src dest
srcs=("$@")
setx dest=last_value srcs
array_del_last srcs
if [ $# -eq 2 ]; then
if [ -d "$dest" ]; then
: # ce cas sera traité ci-dessous
elif [ -e "$dest" ]; then
eerror "$dest: refus d'écraser la destination"
return 1
else
src="${srcs[0]}"
copy_link "$src" "$dest"
return $?
fi
fi
[ -d "$dest" ] || {
eerror "$dest: doit être un répertoire"
return 1
}
local r=0
for src in "${srcs[@]}"; do
copy_link "$src" "$dest" || r=$?
done
return $r
}
##@inc]base.tools
##@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
local first="${1:1}"; shift
echo -n -
echo "$first" "$@"
else
echo "$@"
fi
}
function recho_() {
if [[ "${1:0:2}" == -[eEn] ]]; then
local first="${1:1}"; shift
echo -n -
echo -n "$first" "$@"
else
echo -n "$@"
fi
}
function _qval() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function should_quote() {
local s="$*"
local l="${#s}"
[ $l -eq 0 -o $l -gt 80 ] && return 0
s="${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 qwc() {
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
local r a b c
while [ -n "$s" ]; do
a=; b=; c=
a=; [[ "$s" == *\** ]] && { a="${s%%\**}"; a=${#a}; }
b=; [[ "$s" == *\?* ]] && { b="${s%%\?*}"; b=${#b}; }
c=; [[ "$s" == *\[* ]] && { c="${s%%\[*}"; c=${#c}; }
if [ -z "$a" -a -z "$b" -a -z "$c" ]; then
r="$r\"$s\""
break
fi
if [ -n "$a" ]; then
[ -n "$b" ] && [ $a -lt $b ] && b=
[ -n "$c" ] && [ $a -lt $c ] && c=
fi
if [ -n "$b" ]; then
[ -n "$a" ] && [ $b -lt $a ] && a=
[ -n "$c" ] && [ $b -lt $c ] && c=
fi
if [ -n "$c" ]; then
[ -n "$a" ] && [ $c -lt $a ] && a=
[ -n "$b" ] && [ $c -lt $b ] && b=
fi
if [ -n "$a" ]; then # PREFIX*
a="${s%%\**}"
s="${s#*\*}"
[ -n "$a" ] && r="$r\"$a\""
r="$r*"
elif [ -n "$b" ]; then # PREFIX?
a="${s%%\?*}"
s="${s#*\?}"
[ -n "$a" ] && r="$r\"$a\""
r="$r?"
elif [ -n "$c" ]; then # PREFIX[class]
a="${s%%\[*}"
b="${s#*\[}"; b="${b%%\]*}"
s="${s:$((${#a} + ${#b} + 2))}"
[ -n "$a" ] && r="$r\"$a\""
r="$r[$b]"
fi
done
recho_ "$r"
}
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=\"\$*\""
}
function _setv() {
local __s_var="$1"; shift
eval "$__s_var=\"\$*\""
}
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 echo_setv2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
if [ $# -eq 0 ]; then
echo_setv "$__s_var" "${!__s_var}"
else
echo_setv "$__s_var" "$@"
fi
}
function seta() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=(\"\$@\")"
}
function _seta() {
local __s_array="$1"; shift
eval "$__s_array=(\"\$@\")"
}
function echo_seta() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
echo "$__s_var=($(qvals "$@"))"
}
function echo_seta2() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
elif [ $# -eq 0 ]; then
eval "set -- \"\${$__s_var[@]}\""
fi
echo "$__s_var=($(qvals "$@"))"
}
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
}
function is_defined() {
[ -n "$(declare -p "$1" 2>/dev/null)" ]
}
function is_array() {
case "$(declare -p "$1" 2>/dev/null)" in declare\ -a*) return 0;; esac
return 1
}
function upvar() {
if unset -v "$1"; then
if [ $# -eq 2 ]; then
eval "$1=\"\$2\""
else
eval "$1=(\"\${@:2}\")"
fi
fi
}
function array_upvar() {
unset -v "$1" && eval "$1=(\"\${@:2}\")"
}
function upvars() {
while [ $# -gt 0 ]; do
case "$1" in
-a)
unset -v "$2" && eval "$2=(\"\${@:3}\")"
break
;;
-a*)
unset -v "$2" && eval "$2=(\"\${@:3:${1#-a}}\")"
shift $((${1#-a} + 2)) || return 1
;;
*)
unset -v "$1" && eval "$1=\"\$2\""
shift; shift
;;
esac
done
}
function __ab_process_pending() {
local -a values
case "$mode" in
cmd) values="$("${pending[@]}")";;
ssplit) eval "values=($("${pending[@]}"))";;
lsplit) eval "values=($("${pending[@]}" | qlines))";;
add) values=("${pending[@]}");;
esac
cmd=("${cmd[@]}" "${values[@]}")
pending=()
}
function array_buildcmd() {
local desta="$1"; shift; local "$desta"
local mode=add
local -a pending cmd
while [ $# -gt 0 ]; do
case "$1" in
++c|++cmd|++) __ab_process_pending; mode=cmd;;
++s|++ssplit) __ab_process_pending; mode=ssplit;;
++l|++lsplit) __ab_process_pending; mode=lsplit;;
++a|++add) __ab_process_pending; mode=add;;
*) pending=("${pending[@]}" "$1");;
esac
shift
done
__ab_process_pending
array_upvar "$desta" "${cmd[@]}"
}
function buildcmd() {
local -a args
array_buildcmd args "$@"
qvals "${args[@]}"
}
function evalcmd() {
local -a args
array_buildcmd args "$@"
"${args[@]}"
}
##@inc]base.core
##@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//\//\\/}"
s="${s//
/\\n}"
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
}
function _qsql() {
local q="'" qq="''"
echo "${*//$q/$qq}"
}
function qsql() {
local q="'" qq="''"
echo "'${*//$q/$qq}'"
}
##@inc]base.quote
##@inc[base.string
## Fonctions de base: gestion des valeurs chaines 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 strops() {
local -a __s_tmp
local __s_value="$1"; shift
while [ $# -gt 0 ]; do
case "$1" in
:-*|:=*|:\?*|:+*) eval '__s_value="${'"${__s_value}$1"'}"';;
d|deref) __s_value="${!__s_value}";;
dc|dcount|ds|dsize)
__s_value="${__s_value}[@]"
__s_tmp=("${!__s_value}")
__s_value="${#__s_tmp[@]}"
;;
\#*|%*|/*|:*|^*|,*) eval '__s_value="${__s_value'"$1"'}"';;
l|length) __s_value="${#__s_value}";;
=|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge)
__s_tmp=(\[ "$__s_value" "$@" ]); "${__s_tmp[@]}"; return $?;;
-n|-z) __s_tmp=(\[ "$1" "$__s_value" ]); "${__s_tmp[@]}"; return $?;;
+#*) eval '__s_value="'"${1#+#}"'$__s_value"';;
-#*) eval '__s_value="${__s_value'"${1#-}"'}"';;
+%*) eval '__s_value="$__s_value"'"${1#+%}";;
+*) eval '__s_value="$__s_value"'"${1#+}";;
-%*) eval '__s_value="${__s_value'"${1#-}"'}"';;
-*) eval '__s_value="${__s_value%'"${1#-}"'}"';;
mid|strmid) eval '__s_value="$(strmid "$2" "$__s_value")"'; shift;;
repl|strrepl) eval '__s_value="$(strrepl "$2" "$3" "$__s_value")"'; shift; shift;;
*) echo 1>&2 "strops: unknown operator: $1";;
esac
shift
done
echo "$__s_value"
}
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" ]'
}
function strsplitf() {
[ $# -gt 0 ] || return 127
local func count
func="$1"; shift
count=$#
if [ $count -gt 0 ]; then
eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126
fi
"$func" "$@"
}
function strecho() { recho "$@"; }
function strqvals() {
qvals "$@"
}
function strqlines() {
local -a lines
_setax lines cat "$@"
qvals "${lines[@]}"
}
function strqarray() {
local __a __s="qvals"
for __a in "$@"; do __s="$__s \"\${$__a[@]}\""; done
eval "$__s"
}
function evals() {
local __e_val __e_arg __e_r=0
local __e_firstcmd __e_firstarg __e_splitf
local -a __e_cmd
__e_firstcmd=1
while [ $# -gt 0 ]; do
__e_cmd=()
__e_firstarg=1 # premier argument
__e_splitf= # premier argument après splitf
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
if [ -n "$__e_firstarg" ]; then
__e_cmd=("str$__e_arg")
__e_firstarg=
[ "$__e_arg" == "splitf" ] && __e_splitf=1
elif [ -n "$__e_splitf" ]; then
__e_cmd=("${__e_cmd[@]}" "str$__e_arg")
__e_splitf=
else
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
fi
done
if [ -n "$__e_firstcmd" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_firstcmd=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
##@inc]base.string
##@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} -gt 0 ] || return 1
v="${v//[0-9]/}"
[ -z "$v" ]
}
function ispnum() {
[ ${#1} -gt 0 ] || return 1
[ -z "${1//[0-9]/}" ]
}
function isrnum() {
[ ${#1} -gt 0 ] || return 1
local v="${1#-}"
[ ${#v} -gt 0 ] || return 1
v="${v//./}"
v="${v//,/}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function evali() {
echo "$(($*))"
}
##@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 setyesval() {
is_yes "$2" && _setv "$1" 1 || _setv "$1" ""
}
function normyesval() {
is_yes "${2:-"${!1}"}" && _setv "$1" 1 || _setv "$1" ""
}
function normyesvals() {
local __nyv_yesvar
for __nyv_yesvar in "$@"; do
is_yes "${!__nyv_yesvar}" && _setv "$__nyv_yesvar" 1 || _setv "$__nyv_yesvar" ""
done
}
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
uprovide base.compat
urequire base.core
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"; }
urequire base.quote
function quote_awk() { _qawk "$@"; }
function quoted_awk() { qawk "$@"; }
function quote_seds() { qseds "$@"; }
function quote_form() { _qform "$@"; }
function quoted_form() { qform "$@"; }
function set_array_cmd() {
if [ $# -eq 1 ]; then echo_seta "$1"
elif [ "$2" == @ ]; then echo_seta "$1" "${@:3}"
else eval "echo_seta \"\$1\" \"\${$2[@]}\""
fi
}
function set_array() {
eval "$(set_array_cmd "$@")"
}
if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then
urequire base.string
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[*]}"
}
urequire base.bool
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
##@inc[base.deprecated
## Fonctions dépréciées
uprovide base.deprecated
function set_array_cmd() {
if [ $# -eq 1 ]; then echo_seta2 "$1"
elif [ "$2" == @ ]; then echo_seta "$1" "${@:3}"
else eval "echo_seta \"\$1\" \"\${$2[@]}\""
fi
}
function set_array() {
eval "$(set_array_cmd "$@")"
}
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
recho "$s"
}
##@inc]base.deprecated
uprovide base
urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.tools base.compat
urequire base.deprecated
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" != '"$(qval "$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" == '"$(qval "$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" == '"$(qval "$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" == '"$(qvalm "$2")"' ]; then
return 0
fi
done'
return 1
}
function array_icontains() {
local __ac_v
eval 'for __ac_v in "${'"$1"'[@]}"; do
if [ "$(strlower "$__ac_v")" == '"$(strlower "$(qval "$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" == '"$(qval "$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 "recho \"\${$1[@]:0:1}\""
}
function last_value() {
eval "recho \"\${$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
recho "$__aj_j"
elif [ "$__aj_an" != "\$@" -a -n "$3" ]; then
recho "$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")) }')"
case "$value" in
=*) value="${value#=}";;
+*) value="$(($now + ${value#+} * 86400))";;
-*) 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", 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";;
t|ts|timestamp) echo "$value";;
*) recho "$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
recho "$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#$HOME/}" != "$path" ] && path="~${path#$HOME}"
recho "$path"
}
function ppath2() {
local path="$1" cwd="$2"
path="$(abspath "$path")" # essayer de normaliser le chemin
[ -n "$cwd" ] || cwd="$(pwd)"
[ "$path" = "$cwd" ] && path="../$(basename -- "$path")"
[ "$cwd" != "/" -a "$cwd" != "$HOME" ] && path="${path#$cwd/}"
[ "${path#$HOME/}" != "$path" ] && path="~${path#$HOME}"
recho "$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
recho "${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"
_setv "$__sw_dd" "$__sw_d"
_setv "$__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 readlinka() {
if [ -L "$1" ]; then
local linkdir="$(dirname -- "$1")"
abspath "$(readlink "$1")" "$linkdir"
else
abspath "$1"
fi
}
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
recho "$reldir$file"
else
recho "$basedir/$file"
fi
break
fi
shift
done
}
function update_link() {
[ -L "$2" ] || return 1
local dest link="$2"
local linkdir="$(dirname "$link")"
local ldest="$(readlink "$link")"
if [ "${ldest#/}" != "$ldest" ]; then
dest="$(abspath "$1")"
else
dest="$(relpath "$1" "$linkdir")"
fi
if [ "$dest" == "$ldest" ]; then
: # pas besoin de mettre à jour
elif [ -d "$link" ]; then
rm -f "$link" && ln -s "$dest" "$link"
else
ln -sf "$dest" "$link"
fi
}
function update_links() {
[ -n "$1" ] || return 1
local dest="$1"; shift
local r=0 link
for link in "$@"; do
update_link "$dest" "$link" || r=$?
done
return $r
}
function move_link() {
[ -n "$1" -a -n "$2" ] || return 1
local link="$1" dest="$2"
[ -d "$dest" ] && dest="$dest/$(basename -- "$link")"
dest="$(abspath "$dest")"
if [ -L "$link" ]; then
link="$(abspath "$link")"
[ "$dest" == "$link" ] && return 0
ldest="$(readlinka "$link")"
mv "$link" "$dest" || return 1
update_link "$ldest" "$dest"
else
[ "$dest" == "$link" ] && return 0
mv "$link" "$dest"
fi
}
function copy_link() {
[ -n "$1" -a -n "$2" ] || return 1
local link="$1" dest="$2"
[ -d "$dest" ] && dest="$dest/$(basename -- "$link")"
dest="$(abspath "$dest")"
if [ -L "$link" ]; then
link="$(abspath "$link")"
[ "$dest" == "$link" ] && return 0
ldest="$(readlinka "$link")"
cp -P "$link" "$dest" || return 1
update_link "$ldest" "$dest"
else
[ "$dest" == "$link" ] && return 0
cp "$link" "$dest"
fi
}
function array_find_links() {
local -a __afl_links __afl_result
local __afl_dir="${3:-.}"
local __afl_dest __afl_destname __afl_link __afl_linkdir __afl_ldest
__afl_dest="$(abspath "$2")"
__afl_destname="${__afl_dest##*/}"
array_from_lines __afl_links "$(find "$__afl_dir" -type l)"
for __afl_link in "${__afl_links[@]}"; do
__afl_ldest="$(readlink "$__afl_link")"
if [ "$__afl_ldest" != "$__afl_destname" ]; then
[[ "$__afl_ldest" == */"$__afl_destname" ]] || continue
fi
__afl_link="$(abspath "$__afl_link" "$__afl_dir")"
__afl_linkdir="$(dirname -- "$__afl_link")"
__afl_ldest="$(abspath "$__afl_ldest" "$__afl_linkdir")"
if [ "$__afl_ldest" == "$__afl_dest" ]; then
array_add __afl_result "$__afl_link"
fi
done
array_copy "$1" __afl_result
}
function list_links() {
local -a links
array_find_links links "$@"
array_to_lines links
}
function move_file() {
[ -n "$1" -a -n "$2" ] || return 1
local src="$1" dest="$2" link
shift; shift
[ -d "$dest" ] && dest="$dest/$(basename -- "$src")"
move_link "$src" "$dest" || return 1
update_links "$dest" "$@"
}
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 [ -n "$3" ]; then return 0
elif [ -f "$2" ]; then testdiff "$1" "$2"
else return 0
fi
}
function testnewer() {
[ -n "$3" ] && return 0
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 python2 && return 0
progexists python && return 0
return 1
}
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)
__CPNOVCS_INCLUDE_VCS= # ne pas ignorer les répertoires de VCS
function cpnovcs() {
local src="$1" destdir="$2"
[ -d "$destdir" ] || mkdir -p "$destdir" || return 1
if progexists rsync; then
local -a novcs
if [ -z "$__CPNOVCS_INCLUDE_VCS" ]; then
local gitexclude=/.git/
[ "${src%/}" == "$src" ] && gitexclude="/$(basename -- "$src")$gitexclude"
novcs=(--exclude CVS/ --exclude .svn/ --exclude "$gitexclude")
fi
rsync -a ${__CPNOVCS_RSYNC_SLOW:+-c} "${novcs[@]}" "${__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 cpvcs() {
local __CPNOVCS_INCLUDE_VCS=1
cpnovcs "$@"
}
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/[\xE2\x80\x90\xE2\x80\x91\xE2\x80\x92\xE2\x80\x93\xE2\x80\x94\xE2\x80\x95]/-/g
s/[]/\x27/g
s/[«»“”]/"/g
s/[\xC2\xA0\xE2\x80\x87\xE2\x80\xAF\xE2\x81\xA0]/ /g
s/[\xE2\x80\xA6]/.../g
s/[œ]/oe/g
s/[Œ]/OE/g
s/[æ]/ae/g
s/[Æ]/AE/g
s/a\xCC\x80/à/g
s/e\xCC\x81/é/g; s/e\xCC\x80/è/g; s/e\xCC\x82/ê/g; s/e\xCC\x88/ë/g
s/i\xCC\x88/ï/g; s/i\xCC\x82/î/g
s/o\xCC\x82/ô/g; s/o\xCC\x88/ö/g
s/u\xCC\x88/ü/g; s/u\xCC\x82/û/g
s/c\xCC\xA7/ç/g
s/A\xCC\x80/À/g
s/E\xCC\x81/É/g; s/E\xCC\x80/È/g; s/E\xCC\x82/Ê/g; s/E\xCC\x88/Ë/g
s/I\xCC\x88/Ï/g; s/I\xCC\x82/Î/g
s/O\xCC\x82/Ô/g; s/O\xCC\x88/Ö/g
s/U\xCC\x88/Ü/g; s/U\xCC\x82/Û/g
s/C\xCC\xA7/Ç/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
recho "$f"
done
cd "$curdir"
}
function __la_cmd() {
[ $# -gt 0 ] || set '*'
local arg
local cmd="/bin/ls -1d"
for arg in "$@"; do
arg="$(qwc "$arg")"
cmd="$cmd $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" ] && recho "$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" ] && recho "$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}"
[ "$NUTOOLS_SH_ARCHIVE_SUPPORT" ] && name="${name%.sh}"
[ "$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
elif [ "$NUTOOLS_SH_ARCHIVE_SUPPORT" ] && endswith "$arch" .sh; then
(
arch="$(abspath "$arch")"
cd "$destdir"
"${BASH:-/bin/sh}" "$arch" --tar xf "$@"
) || 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}"
[ "$NUTOOLS_SH_ARCHIVE_SUPPORT" ] && basename="${basename%.sh}"
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}"
[ "$NUTOOLS_SH_ARCHIVE_SUPPORT" ] && appname="${appname%.sh}"
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=$(qval "$__estack")
__tlevel=$(qval "$__tlevel")
export __estack __tlevel
exec ${BASH:-/bin/sh} $(qvals "$@")"
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
host="${host%%.*}"
[ "$host" == localhost -o "$host" == "$MYHOSTNAME" ] && 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
eimportant "Vous pouvez tenter de relancer le script sur ${userhosts[0]}"
eimportant "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.
En l'occurence, ce script est accédé par le chemin $script et ce chemin doit exister aussi sur le serveur distant."
if ask_yesno "Voulez-vous tenter de relancer le script sur l'hôte distant?" X; 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="$(qvals cd "$path"); "
cmd="$cmd$(qvals "$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 num(s) {
if (s ~ /^[0-9]+$/) return int(s)
else return s
}
function ord(s, i) {
s = substr(s, 1, 1)
i = index(" !\"#$%&'\''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", s)
if (i != 0) i += 32 - 1
return i
}
function hex(i, s) {
s = sprintf("%x", i)
if (length(s) < 2) s = "0" s
return s
}
function qhtml(s) {
gsub(/&/, "\\&amp;", s)
gsub(/"/, "\\&quot;", s)
gsub(/>/, "\\&gt;", s)
gsub(/</, "\\&lt;", s)
return s
}
function unquote_html(s) {
gsub(/&lt;/, "<", s)
gsub(/&gt;/, ">", s)
gsub(/&quot;/, "\"", s)
gsub(/&amp;/, "\\&", s)
return s
}
function qawk(s) {
gsub(/\\/, "\\\\", s)
gsub(/"/, "\\\"", s)
gsub(/\n/, "\\n", s)
return "\"" s "\""
}
function qval(s) {'"
gsub(/'/, \"'\\\\''\", s)
return \"'\" s \"'\"
"'}
function sqval(s) {
return " " qval(s)
}
function qvals( i, line) {
line = ""
for (i = 1; i <= NF; i++) {
if (i > 1) line = line " "
line = line qval($i)
}
return line
}
function sqvals() {
return " " qvals()
}
function qarr(values, prefix, i, count, line) {
line = prefix
count = array_len(values)
for (i = 1; i <= count; i++) {
if (i > 1 || line != "") line = line " "
line = line qval(values[i])
}
return line
}
function qregexp(s) {
gsub(/[[\\.^$*+?()|{]/, "\\\\&", s)
return s
}
function qsubrepl(s) {
gsub(/\\/, "\\\\", s)
gsub(/&/, "\\\\&", s)
return s
}
function qgrep(s) {
gsub(/[[\\.^$*]/, "\\\\&", s)
return s
}
function qegrep(s) {
gsub(/[[\\.^$*+?()|{]/, "\\\\&", s)
return s
}
function qsql(s, suffix) {'"
gsub(/'/, \"''\", s)
return \"'\" s \"'\" (suffix != \"\"? \" \" suffix: \"\")
"'}
function cqsql(s, suffix) {
return "," qsql(s, suffix)
}
function unquote_mysqlcsv(s) {
gsub(/\\n/, "\n", s)
gsub(/\\t/, "\t", s)
gsub(/\\0/, "\0", s)
gsub(/\\\\/, "\\", s)
return s
}
function sval(s) {
if (s == "") return s
else return " " s
}
function cval(s, suffix) {
if (s == "") return s
else return "," s (suffix != ""? " " suffix: "")
}
function quote_html(s) { return qhtml(s) }
function quote_value(s) { return qval(s) }
function qsval(s) { return sqval(s) }
function quoted_values() { return qvals() }
function qsvals(s) { return sqvals(s) }
function quote_regexp(s) { return qregexp(s) }
function quote_subrepl(s) { return qsubrepl(s) }
function quote_grep(s) { return qgrep(s) }
function quote_egrep(s) { return qegrep(s) }
function quote_sql(s) { return qsql(s) }
function __parse_date_fr(date, parts, y, m, d) {
if (match(date, /([0-9][0-9]?)\/([0-9][0-9]?)\/([0-9][0-9][0-9][0-9])/, parts)) {
y = int(parts[3])
m = int(parts[2])
d = int(parts[1])
return mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d))
} else if (match(date, /([0-9][0-9]?)\/([0-9][0-9]?)\/([0-9][0-9])/, parts)) {
basey = int(strftime("%Y")); basey = basey - basey % 100
y = basey + int(parts[3])
m = int(parts[2])
d = int(parts[1])
return mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d))
}
return -1
}
function __parse_date_mysql(date, parts, y, m, d) {
if (match(date, /([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])/, parts)) {
y = int(parts[1])
m = int(parts[2])
d = int(parts[3])
return mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d))
}
return -1
}
function __parse_date_any(date, serial) {
serial = __parse_date_fr(date)
if (serial == -1) serial = __parse_date_mysql(date)
return serial
}
function date_serial(date) {
return __parse_date_any(date)
}
function date_parse(date, serial) {
serial = __parse_date_any(date)
if (serial == -1) return date
return strftime("%d/%m/%Y", serial)
}
function date_monday(date, serial, dow) {
serial = __parse_date_any(date)
if (serial == -1) return date
dow = strftime("%u", serial)
serial -= (dow - 1) * 86400
return strftime("%d/%m/%Y", serial)
}
function date_add(date, nbdays, serial) {
serial = __parse_date_any(date)
if (serial == -1) return date
serial += nbdays * 86400
return strftime("%d/%m/%Y", serial)
}
function mkindices(values, indices, i, j) {
array_new(indices)
j = 1
for (i in values) {
indices[j++] = int(i)
}
return asort(indices)
}
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 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() {
[ -z "$__ULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local __ULIB_AWKDEF_SET_X=1; } # désactiver set -x pour cette fonction
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($(qawk "$__ad_value") + 0)"
elif [ -n "$__ad_str" ]; then
echo "$__ad_name = $(qawk "$__ad_value")"
elif [ ${#__ad_value} -lt 256 ] && isnum "$__ad_value"; then
echo "$__ad_name = $__ad_value"
else
echo "$__ad_name = $(qawk "$__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]=$(qawk "$__ad_arg")"
__ad_i=$(($__ad_i + 1))
done
eval "echo \"\${__ad_name}_count = \${#$__ad_value}\""
fi
shift
done
echo "}"
for __ad_arg in "$@"; do
recho "$__ad_arg"
done
fi
[ -n "$__ULIB_AWKDEF_SET_X" ] && set -x; return 0
}
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[@]}")"
[ -n "$UTOOLS_AWKRUN_DEBUG" ] && estep "Script awkrun: $__ar_script"
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 -XFR "$@"
else
cat
fi
}
function utools_local() {
local arg
[ $# -gt 0 ] || 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 stdredir() {
local __redirs __in __out __err
if [ -n "$1" -o "$1" == /dev/stdin ]; then
if [ "${1#<}" != "$1" ]; then
__in="${1#<}"
else
__in="$1"
fi
__redirs="$__redirs"' <"$__in"'
fi; shift
if [ -n "$1" -o "$1" == /dev/stdout ]; then
if [ "${1#>>}" != "$1" ]; then
__out="${1#>>}"
__redirs="$__redirs"' >>"$__out"'
elif [ "${1#>}" != "$1" ]; then
__out="${1#>}"
__redirs="$__redirs"' >"$__out"'
else
__out="$1"
__redirs="$__redirs"' >"$__out"'
fi
fi; shift
if [ -n "$1" -o "$1" == /dev/stderr ]; then
if [ "${1#>>}" != "$1" ]; then
__err="${1#>>}"
__redirs="$__redirs"' 2>>"$__err"'
elif [ "${1#>}" != "$1" ]; then
__err="${1#>}"
__redirs="$__redirs"' 2>"$__err"'
else
__err="$1"
__redirs="$__redirs"' 2>"$__err"'
fi
fi; shift
eval '"$@"'"$__redirs"
}
function isatty() {
tty -s <&1
}
function in_isatty() {
tty -s
}
function out_isatty() {
tty -s <&1
}
function err_isatty() {
tty -s <&2
}
function die() { [ $# -gt 0 ] && eerror "$@"; exit 1; }
function exit_with { if [ $# -gt 0 ]; then "$@"; fi; exit $?; }
function die_with { [ $# -gt 0 ] && eerror "$1"; shift; [ $# -gt 0 ] && "$@"; exit 1; }
function die_unless() {
local count=$#
if [ $count -eq 0 ]; then
exit 1
elif [ $count -eq 1 ]; then
"$@" || exit $?
else
local m r
m="${@:$count}"
count=$(($count - 1))
set -- "${@:1:$count}"
if "$@"; then
:
else
r=$?
eerror "$m"
exit $r
fi
fi
}
function eerror_unless() {
local count=$#
if [ $count -eq 0 ]; then
return 1
elif [ $count -eq 1 ]; then
"$@" || return $?
else
local m r
m="${@:$count}"
count=$(($count - 1))
set -- "${@:1:$count}"
if "$@"; then
:
else
r=$?
eerror "$m"
return $r
fi
fi
}
function die_if() {
local count=$#
if [ $count -eq 0 ]; then
:
elif [ $count -eq 1 ]; then
"$@" && exit 1
else
local m r
m="${@:$count}"
count=$(($count - 1))
set -- "${@:1:$count}"
if "$@"; then
eerror "$m"
exit 1
fi
fi
}
function eerror_if() {
local count=$#
if [ $count -eq 0 ]; then
:
elif [ $count -eq 1 ]; then
"$@" && return 1
else
local m r
m="${@:$count}"
count=$(($count - 1))
set -- "${@:1:$count}"
if "$@"; then
eerror "$m"
return 1
fi
fi
}
function noerror() {
[ $# -gt 0 ] || set :
"$@" || return 0
}
function noout() {
[ $# -gt 0 ] || return 0
"$@" >/dev/null
}
function noerr() {
[ $# -gt 0 ] || return 0
"$@" 2>/dev/null
}
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
recho "$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
recho_ "$src"
else
recho_ "$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
_setv "$__tie_var" "$(iconv -f "$__tie_from" -t "$__tie_to" <<<"${!__tie_var}")"
fi
}
function uread() {
[ $# -gt 0 ] || 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
recho "$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() { tooenc "$(__edate)${__tlevel}.E $(__indent "$1")"; }
function __estepw() { tooenc "$(__edate)${__tlevel}.W $(__indent "$1")"; }
function __estepn() { tooenc "$(__edate)${__tlevel}.N $(__indent "$1")"; }
function __estepi() { tooenc "$(__edate)${__tlevel}.I $(__indent "$1")"; }
function __estep_() { tooenc_ "$(__edate)${__tlevel}. $(__indent "$1")"; }
function __estepe_() { tooenc_ "$(__edate)${__tlevel}.E $(__indent "$1")"; }
function __estepw_() { tooenc_ "$(__edate)${__tlevel}.W $(__indent "$1")"; }
function __estepn_() { tooenc_ "$(__edate)${__tlevel}.N $(__indent "$1")"; }
function __estepi_() { tooenc_ "$(__edate)${__tlevel}.I $(__indent "$1")"; }
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 recho "$__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="$(qvals "$@")"
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="$(qvals "$@")"
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 [ $# -gt 0 ]; 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 [ $# -gt 0 ]; 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 && [ $# -gt 0 ] && __edotd "$*" 1>&2
return $s
}
function edotw() {
local s=$?
show_info || return
eflush
[ -n "$1" ] && s="$1"
shift
__edotw 1>&2
show_verbose && [ $# -gt 0 ] && __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 __elinedots() {
ebegin "$1"
local line
if show_debug; then
while read line; do
__edoto 1>&2
__edotd "$line" 1>&2
done
else
while read line; do
__edoto 1>&2
done
fi
eend
}
function elinedots() {
local msg="$1"; shift
if [ $# -gt 0 ]; then
"$@" | __elinedots "$msg"
else
__elinedots "$msg"
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
__eecho_ "$message" 1>&2
else
OENC="$UTF8" __eecho_ "Voulez-vous continuer?" 1>&2
fi
OENC="$UTF8" tooenc_ " $prompt " 1>&2
uread r
is_yes "${r:-$default}"
else
is_yes "$default"
fi
}
function ask_any() {
local interactive=1
if [[ "$1" == -* ]]; then
if [ "$1" != -- ]; then
check_interaction "$1" || interactive=
fi
shift
else
check_interaction -c || interactive=
fi
local format="${2:-+Oq}"
format="${format/+O/On}"
format="${format/+N/oN}"
if [ -n "$interactive" ]; then
format="${format/+C/oN}"
format="${format/+X/On}"
else
format="${format/+C/On}"
format="${format/+X/oN}"
fi
local i count="${#format}"
if [ -n "$interactive" ]; then
eflush
local message="${1:-Voulez-vous continuer?}"
local prompt="[$format]"
local r f lf defi
while true; do
__eecho_ "$message $prompt " 1>&2
uread r
r="$(strlower "${r:0:1}")"
i=0; defi=
while [ $i -lt $count ]; do
f="${format:$i:1}"
lf="$(strlower "$f")"
[ "$r" == "$lf" ] && return $i
if [ -z "$defi" ]; then
[ -z "${f/[A-Z]/}" ] && defi="$i"
fi
if [ "$lf" == o ]; then
case "$r" in o|y|1|v|t) return $i;; esac
elif [ "$lf" == n ]; then
case "$r" in n|f|0) return $i;; esac
fi
i=$(($i + 1))
done
[ -z "$r" ] && return ${defi:-0}
done
else
i=0
while [ $i -lt $count ]; do
f="${format:$i:1}"
[ -z "${f/[A-Z]/}" ] && return $i
i=$(($i + 1))
done
return 0
fi
}
function read_value() {
local -a __rv_opts __rv_readline=1 __rv_showdef=1 __rv_nl=
__rv_opts=()
[ -n "$UTOOLS_NO_READLINE" ] && __rv_readline=
__rv_read "$@"
}
function read_password() {
local -a __rv_opts __rv_readline= __rv_showdef= __rv_nl=1
__rv_opts=(-s)
__rv_read "$@"
}
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
_setv "$__rv_v" "$__rv_d"
return 0
fi
eflush
local __rv_r
while true; do
if [ -n "$__rv_msg" ]; then
__eecho_ "$__rv_msg" 1>&2
else
OENC="$UTF8" __eecho_ "Entrez la valeur" 1>&2
fi
if [ -n "$__rv_readline" ]; then
OENC="$UTF8" tooenc_ ": " 1>&2
uread -e ${__rv_d:+-i"$__rv_d"} "${__rv_opts[@]}" __rv_r
else
if [ -n "$__rv_d" ]; then
if [ -n "$__rv_showdef" ]; then
tooenc_ " [$__rv_d]" 1>&2
else
tooenc_ " [****]" 1>&2
fi
fi
OENC="$UTF8" tooenc_ ": " 1>&2
uread "${__rv_opts[@]}" __rv_r
[ -n "$__rv_nl" ] && echo
fi
__rv_r="${__rv_r:-$__rv_d}"
if [ -n "$__rv_r" ] || ! is_yes "$__rv_re"; then
_setv "$__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" ] && __eecho "=== $__sm_title ===" 1>&2
__sm_i=1
for __sm_option in "${__sm_options[@]}"; do
if [ "$__sm_option" == "$__sm_default" ]; then
__eecho "$__sm_i*- $__sm_option" 1>&2
else
__eecho "$__sm_i - $__sm_option" 1>&2
fi
let __sm_i=$__sm_i+1
done
fi
if [ -n "$__sm_yourchoice" ]; then
__eecho_ "$__sm_yourchoice" 1>&2
else
OENC="$UTF8" __eecho_ "Entrez le numéro de l'option choisie" 1>&2
fi
OENC="$UTF8" tooenc_ ": " 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
OENC="$UTF8" tooenc "" 1>&2
__sm_c=0
fi
done
_setv "$__sm_option_var" "$__sm_option"
}
function actions_menu() {
local -a __am_action_descs __am_options __am_void_actions
local __am_tmp __am_select_action __am_select_option __am_title __am_optyc __am_actyc
local __am_default_action=auto __am_quit_action=auto
local __am_default_option=
local -a __am_args
parse_opts \
-t: __am_title= \
-m: __am_optyc= \
-M: __am_actyc= \
-e: __am_void_actions \
-d: __am_default_action= \
-q: __am_quit_action= \
-o: __am_default_option= \
@ __am_args -- "$@" && set -- "${__am_args[@]}" || { eerror "$__am_args"; return 1; }
__am_tmp="${1:-action}"; __am_select_action="${!__am_tmp}"
__am_tmp="${2:-option}"; __am_select_option="${!__am_tmp}"
[ -n "$__am_default_option" ] && __am_select_option="$__am_default_option"
array_copy __am_action_descs "${3:-actions}"
array_copy __am_options "${4:-options}"
eerror_unless [ ${#__am_action_descs[*]} -gt 0 ] "Vous devez spécifier le tableau des actions" || return
__actions_menu || return 1
_setv "${1:-action}" "$__am_select_action"
_setv "${2:-option}" "$__am_select_option"
}
function __actions_menu() {
local title="$__am_title"
local optyc="$__am_optyc" actyc="$__am_actyc"
local default_action="$__am_default_action"
local quit_action="$__am_quit_action"
local select_action="$__am_select_action"
local select_option="$__am_select_option"
local -a action_descs options void_actions
array_copy action_descs __am_action_descs
array_copy options __am_options
array_copy void_actions __am_void_actions
local no_options
array_isempty options && no_options=1
local -a actions
local tmp action name
for tmp in "${action_descs[@]}"; do
splitfsep2 "$tmp" : action name
[ -n "$action" ] || action="${name:0:1}"
action="$(strlower "$action")"
array_addu actions "$action"
done
if [ "$default_action" == auto ]; then
default_action="$select_action"
if [ -n "$default_action" ]; then
array_contains actions "$default_action" || default_action=
fi
[ -n "$default_action" ] || default_action="${actions[0]}"
fi
default_action="${default_action:0:1}"
default_action="$(strlower "$default_action")"
if [ "$quit_action" == auto ]; then
if [ ${#actions[*]} -gt 1 ]; then
quit_action="${actions[@]:$((-1)):1}"
array_addu void_actions "$quit_action"
fi
fi
quit_action="${quit_action:0:1}"
quit_action="$(strlower "$quit_action")"
local action_title
for tmp in "${action_descs[@]}"; do
splitfsep2 "$tmp" : action name
[ -n "$action" ] || action="${name:0:1}"
[ -n "$name" ] || name="$action"
action="$(strlower "$action")"
if [ -n "$no_options" ]; then
if ! array_contains void_actions "$action"; then
array_del actions "$action"
continue
fi
fi
[ "$action" == "$default_action" ] && name="$name*"
action_title="${action_title:+$action_title/}$name"
done
if [ -n "$default_action" ]; then
array_contains actions "$default_action" || default_action=
fi
if [ -n "$quit_action" ]; then
array_contains actions "$quit_action" || quit_action=
fi
if [ -n "$no_options" ]; then
if array_isempty void_actions; then
eerror "Aucune option n'est définie. Il faut définir le tableau des actions vides"
return 1
fi
__void_actions_menu
else
__options_actions_menu
fi
}
function __void_actions_menu() {
eflush
local c=0 choice
while true; do
if [ $c -eq 0 ]; then
[ -n "$title" ] && __etitle "$title" 1>&2
__eecho_ "=== Actions disponibles: " 1>&2
tooenc "$action_title" 1>&2
fi
if [ -n "$actyc" ]; then
__eecho_ "$actyc" 1>&2
elif [ -n "$optyc" ]; then
__eecho_ "$optyc" 1>&2
else
__eecho_ "Entrez l'action à effectuer" 1>&2
fi
tooenc_ ": " 1>&2
uread choice
if [ -z "$choice" -a -n "$default_action" ]; then
select_action="$default_action"
break
fi
choice="${choice:0:1}"
choice="$(strlower "$choice")"
if array_contains actions "$choice"; then
select_action="$choice"
break
elif [ -n "$choice" ]; then
eerror "$choice: action incorrecte"
else
eerror "vous devez saisir l'action à effectuer"
fi
let c=$c+1
if [ $c -eq 5 ]; then
tooenc "" 1>&2
c=0
fi
done
__am_select_action="$select_action"
__am_select_option=
}
function __options_actions_menu() {
eflush
local c=0 option choice action option
while true; do
if [ $c -eq 0 ]; then
[ -n "$title" ] && __etitle "$title" 1>&2
i=1
for option in "${options[@]}"; do
if [ "$option" == "$select_option" ]; then
tooenc "$i*- $option" 1>&2
else
tooenc "$i - $option" 1>&2
fi
let i=$i+1
done
__estepn_ "Actions disponibles: " 1>&2
tooenc "$action_title" 1>&2
fi
if [ -n "$optyc" ]; then
__eecho_ "$optyc" 1>&2
else
__eecho_ "Entrez l'action et le numéro de l'option choisie" 1>&2
fi
tooenc_ ": " 1>&2
uread choice
if [ -z "$choice" -a -n "$default_action" ]; then
action="$default_action"
if array_contains void_actions "$action"; then
select_action="$action"
select_option=
break
elif [ -n "$select_option" ]; then
select_action="$action"
break
fi
fi
action="${choice:0:1}"
action="$(strlower "$action")"
if array_contains actions "$action"; then
if array_contains void_actions "$action"; then
select_action="$action"
select_option=
break
else
option="${choice:1}"
option="${option// /}"
if [ -z "$option" -a -n "$select_option" ]; then
select_action="$action"
break
elif [ -z "$option" ]; then
eerror "vous devez saisir le numéro de l'option"
elif isnum "$option"; then
if [ $option -gt 0 -a $option -le ${#options[*]} ]; then
select_action="$action"
select_option="${options[$(($option - 1))]}"
break
fi
else
eerror "$option: numéro d'option incorrecte"
fi
fi
elif isnum "$choice"; then
action="$default_action"
if [ -n "$action" ]; then
if array_contains void_actions "$action"; then
select_action="$action"
select_option=
break
else
option="${choice// /}"
if [ -z "$option" ]; then
eerror "vous devez saisir le numéro de l'option"
elif isnum "$option"; then
if [ $option -gt 0 -a $option -le ${#options[*]} ]; then
select_action="$action"
select_option="${options[$(($option - 1))]}"
break
fi
else
eerror "$option: numéro d'option incorrecte"
fi
fi
else
eerror "Vous devez spécifier l'action à effectuer"
fi
elif [ -n "$choice" ]; then
eerror "$choice: action et/ou option incorrecte"
else
eerror "vous devez saisir l'action à effectuer"
fi
let c=$c+1
if [ $c -eq 5 ]; then
tooenc "" 1>&2
c=0
fi
done
__am_select_action="$select_action"
__am_select_option="$select_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
_setv "$1" "$3"
[ -f "$3" -a "$4" == keep ] || >"$3"
else
local __acst_t="$(mktempf "$2")"
autoclean "$__acst_t"
_setv "$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
_setv "$1" "$3"
mkdir -p "$3"
else
local __acst_t="$(mktempd "$2")"
autoclean "$__acst_t"
_setv "$1" "$__acst_t"
fi
}
function debug_tee() {
if show_debug; then
tee "$@"
else
cat
fi
}
function get_user_defaults_file() {
if [ -r "$HOME/etc/default.${HOSTNAME%%.*}/$1" ]; then
echo "$HOME/etc/default.${HOSTNAME%%.*}/$1"
elif [ -r "$HOME/etc/default/$1" ]; then
echo "$HOME/etc/default/$1"
elif [ -n "$UTOOLS_LOCAL_PROFILES" ]; then
echo "$HOME/etc/default.${HOSTNAME%%.*}/$1"
else
echo "$HOME/etc/default/$1"
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.${HOSTNAME%%.*}/$__gd_f" ]; then
__gd_fs=("${__gd_fs[@]}" "$HOME/etc/default.${HOSTNAME%%.*}/$__gd_f")
__gd_found=1
elif [ -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() { local p; [ -z "$NO_COLORS" ] && p="E" || p="ERROR"; tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __ewarn() { local p; [ -z "$NO_COLORS" ] && p="W" || p="WARNING"; tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __enote() { local p; [ -z "$NO_COLORS" ] && p="N" || p="NOTE"; tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}${p}${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() { local p; [ -z "$NO_COLORS" ] && p="!" || p="IMPORTANT"; tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __eattention() { local p; [ -z "$NO_COLORS" ] && p="*" || p="ATTENTION"; tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __einfo() { local p; [ -z "$NO_COLORS" ] && p="I" || p="INFO"; tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __edebug() { local p; [ -z "$NO_COLORS" ] && p="D" || p="DEBUG"; tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estep() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepe() { local p; [ -z "$NO_COLORS" ] && p="." || p=".E"; tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepw() { local p; [ -z "$NO_COLORS" ] && p="." || p=".W"; tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepn() { local p; [ -z "$NO_COLORS" ] && p="." || p=".N"; tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepi() { local p; [ -z "$NO_COLORS" ] && p="." || p=".I"; tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estep_() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepe_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".E"; tooenc_ "$(__edate)${__tlevel}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepw_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".W"; tooenc_ "$(__edate)${__tlevel}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepn_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".N"; tooenc_ "$(__edate)${__tlevel}${COULEUR_VERTE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __estepi_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".I"; tooenc_ "$(__edate)${__tlevel}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; }
function __etitle() { local p; [ -z "$NO_COLORS" ] && p="T" || p="==="; tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}${p} $(get_color _)$(__indent "$1")${COULEUR_NORMALE}"; }
function __ebegin() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}${p}${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 ol rhel fedora centos suse gentoo)
linux32_SYSDISTS=(debianlike debian ubuntu redhatlike ol rhel fedora centos suse gentoo)
linux64_SYSDISTS=(debianlike debian ubuntu redhatlike ol 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=(
forky trixie bookworm bullseye buster stretch jessie wheezy squeeze lenny etch
)
ubuntu_SYSVERS=(
mantic lunar kinetic jammy
impish hirsute groovy focal
eoan disco cosmic bionic
artful zesty yakkety xenial
wily vivid utopic trusty
saucy raring quantal precise
oneiric natty maverick lucid
karmic jaunty intrepid hardy
)
redhatlike_SYSVERS=()
ol_SYSVERS=(ol8 ol7 ol6 redhat8 redhat7 redhat6)
rhel_SYSVERS=(rhel8 rhel7 rhel6 rhel5 rhel4 redhat8 redhat7 redhat6 redhat5 redhat4)
fedora_SYSVERS=(fedora14 fedora13 fedora12 fedora11)
centos_SYSVERS=(centos7 centos6 centos5 centos4 redhat7 redhat6 redhat5 redhat4)
suse_SYSVERS=()
gentoo_SYSVERS=()
SYSVER_ALIASES=(
14=forky 13=trixie 12=bookworm 11=bullseye 10=buster 9=stretch 8=jessie 7=wheezy 6=squeeze 5=lenny 4=etch
23.10=mantic 23.04=lunar 22.10=kinetic 22.04=jammy
21.10=impish 21.04=hirsute 20.10=groovy 20.04=focal
19.10=eoan 19.04=disco 18.10=cosmic 18.04=bionic
17.10=artful 17.04=zesty 16.10=yakkety 16.04=xenial
15.10=wily 15.04=vivid 14.10=utopic 14.04=trusty
13.10=saucy 13.04=raring 12.10=quantal 12.04=precise
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
function __compute_local_sysinfos_data() {
SYSINFOS_DATA=(
"$UNAME_SYSTEM"
"$UNAME_MACHINE"
"$([ -f /etc/debian_version ] && cat /etc/debian_version)"
"$([ -f /etc/gentoo-release ] && cat /etc/gentoo-release)"
"$([ -f /etc/oracle-release ] && cat /etc/oracle-release)"
"$([ -f /etc/redhat-release ] && cat /etc/redhat-release)"
"$([ -f /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist)"
"$([ -f /System/Library/Frameworks/CoreServices.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Resources/version.plist)"
)
}
function __dump_remote_sysinfos_data() {
"${2:-ssh}" "$1" "\
uname -s
echo .----------------.
uname -m
echo .----------------.
[ -f /etc/debian_version ] && cat /etc/debian_version
echo .----------------.
[ -f /etc/gentoo-release ] && cat /etc/gentoo-release
echo .----------------.
[ -f /etc/oracle-release ] && cat /etc/oracle-release
echo .----------------.
[ -f /etc/redhat-release ] && cat /etc/redhat-release
echo .----------------.
[ -f /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist
echo .----------------.
[ -f /System/Library/Frameworks/CoreServices.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Resources/version.plist
echo .----------------."
}
function __build_sysinfos_data() {
awk '
BEGIN {
data = ""
have_data = 0
print "SYSINFOS_DATA=("
}
function read_data() {
if (have_data) data = data "\n"
else have_data = 1
data = data $0
}
function dump_data() {
gsub(/'\''/, "'\'\\\\\'\''", data)
print "'\''" data "'\''"
data = ""
have_data = 0
}
$0 == ".----------------." { dump_data(); next }
{ read_data() }
END {
dump_data()
print ")"
}
'
}
function __compute_sysinfos() {
local system="${SYSINFOS_DATA[0]}"
local machine="${SYSINFOS_DATA[1]}"
local debian_version="${SYSINFOS_DATA[2]}"
local gentoo_release="${SYSINFOS_DATA[3]}"
local oracle_release="${SYSINFOS_DATA[4]}"
local redhat_release="${SYSINFOS_DATA[5]}"
local macosx_plist1="${SYSINFOS_DATA[6]}"
local macosx_plist2="${SYSINFOS_DATA[7]}"
MYSYSNAME=(unknown)
MYSYSDIST=(unknown)
MYSYSVER=(unknown)
if [ "$system" == "Linux" ]; then
case "$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 [ -n "$debian_version" ]; then
case "$debian_version" in
11*|bullseye*) MYSYSDIST=(debian debianlike); MYSYSVER=(bullseye);;
10*|buster*) MYSYSDIST=(debian debianlike); MYSYSVER=(buster);;
9*|stretch*) MYSYSDIST=(debian debianlike); MYSYSVER=(stretch);;
8*|jessie*) MYSYSDIST=(debian debianlike); MYSYSVER=(jessie);;
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 [ -n "$gentoo_release" ]; then
MYSYSDIST=(gentoo)
elif [ -n "$oracle_release" ]; then
MYSYSDIST=(ol rhel redhatlike)
case "$oracle_release" in
Oracle*Linux*release\ 8*) MYSYSVER=(ol8 rhel8 redhat8);;
Oracle*Linux*release\ 7*) MYSYSVER=(ol7 rhel7 redhat7);;
Oracle*Linux*release\ 6*) MYSYSVER=(ol6 rhel6 redhat6);;
esac
elif [ -n "$redhat_release" ]; then
case "$redhat_release" in
Fedora*) MYSYSDIST=(fedora redhatlike);;
Red*Hat*Enterprise*Linux*) MYSYSDIST=(rhel redhatlike);;
CentOS*) MYSYSDIST=(centos redhatlike);;
*) MYSYSDIST=(redhatlike);;
esac
case "$redhat_release" in
Fedora*14*) MYSYSVER=(fedora14);;
Fedora*13*) MYSYSVER=(fedora13);;
Fedora*12*) MYSYSVER=(fedora12);;
Fedora*11*) MYSYSVER=(fedora11);;
Red*Hat*Enterprise*Linux*release\ 8*) MYSYSVER=(rhel8 redhat8);;
Red*Hat*Enterprise*Linux*release\ 7*) MYSYSVER=(rhel7 redhat7);;
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\ 8*) MYSYSVER=(centos8 redhat8);;
CentOS*release\ 7*) MYSYSVER=(centos7 redhat7);;
CentOS*release\ 6*) MYSYSVER=(centos6 redhat6);;
CentOS*release\ 5*) MYSYSVER=(centos5 redhat5);;
CentOS*release\ 4*) MYSYSVER=(centos4 redhat4);;
esac
fi
elif [ "$system" == "Darwin" ]; then
function get_macosx_version() {
local plist
for plist in "$@"; do
[ -n "$plist" ] || continue
echo "$plist" | grep -A 1 CFBundleShortVersionString | grep string | sed 's/.*<string>//g
s/<\/string>.*$//g'
break
done
}
MYSYSNAME=(macosx darwin)
case "$(get_macosx_version "$macosx_plist1" "$macosx_plist2")" in
10.7*) MYSYSDIST=(lion);;
10.6*) MYSYSDIST=(snowleopard);;
10.5*) MYSYSDIST=(leopard);;
10.4*) MYSYSDIST=(tiger);;
10.3*) MYSYSDIST=(panther);;
esac
MYSYSVER=()
fi
}
function compute_local_sysinfos() {
local SYSINFOS_DATA
__compute_local_sysinfos_data
__compute_sysinfos
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 compute_remote_sysinfos() {
local SYSINFOS_DATA
eval "$(__dump_remote_sysinfos_data "$@" | __build_sysinfos_data)"
__compute_sysinfos
}
SYSINFOSLOCALS="\
local -a MYSYSNAME MYSYSDIST MYSYSVER
local MYBITS"
MYSYSNAME=()
MYBITS=
MYSYSDIST=()
MYSYSVER=()
compute_local_sysinfos
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
_setv "$sysdistvar_" "$sysdist_"
_setv "$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
_setv "$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
_setv "$sysdistvar_" "$sysdist_"
break
done
fi
[ -z "${!sysdistvar_}" ] && return
if [ -z "${!sysvervar_}" ]; then
array_copy sysvers_ "${sysdistvar_}_SYSVERS"
for sysver_ in "${sysvers_[@]}"; do
_setv "$sysvervar_" "$sysver_"
break
done
fi
}
function ensure_sysinfos() {
local sysnamevar_="${1:-SYSNAME}"
local sysdistvar_="${2:-SYSDIST}"
local sysvervar_="${3:-SYSVER}"
[ -n "${!sysdistvar_}" ] && _setv "$sysdistvar_" "$(__get_sysdist_alias "${!sysdistvar_}")"
[ -n "${!sysvervar_}" ] && _setv "$sysvervar_" "$(__get_sysver_alias "${!sysvervar_}")"
__fix_sysinfos_upward
__fix_sysinfos_downward
}
function dump_sysinfos() {
local sysname_="${1:-MYSYSNAME}[*]"
local sysdist_="${2:-MYSYSDIST}[*]"
local sysver_="${3:-MYSYSVER}[*]"
echo "\
sysname=(${!sysname_})
sysdist=(${!sysdist_})
sysver=(${!sysver_})
bits=$MYBITS"
}
function get_sysinfos_desc() {
local sysname_="${1:-MYSYSNAME}"; sysname_="${!sysname_}"
local sysdist_="${2:-MYSYSDIST}"; sysdist_="${!sysdist_}"
local sysver_="${3:-MYSYSVER}"; sysver_="${!sysver_}"
echo "$sysname_${sysdist_:+/$sysdist_}${sysver_:+/$sysver_}"
}
function check_sysinfos() {
local sysnamevar_ sysdistvar_ sysvervar_ bitsvar_
if [ "$1" == --vars ]; then
shift
if [[ "$1" != -* ]]; then sysnamevar_="${1:-MYSYSNAME}"; shift; fi
if [[ "$1" != -* ]]; then sysdistvar_="${1:-MYSYSDIST}"; shift; fi
if [[ "$1" != -* ]]; then sysvervar_="${1:-MYSYSVER}"; shift; fi
if [[ "$1" != -* ]]; then bitsvar_="${1:-MYBITS}"; shift; fi
else
sysnamevar_="MYSYSNAME"
sysdistvar_="MYSYSDIST"
sysvervar_="MYSYSVER"
bitsvar_="MYBITS"
fi
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
[ "$sysdist_" == "$value_" ] && break
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
[ "$sysver_" == "$value_" ] && break
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_
}
function unsupported_system() {
local msg="Ce script n'est pas supporté sur $(get_sysinfos_desc)"
[ -n "$*" ] && msg="$msg
Il faut au moins l'un des systèmes suivants: $*"
die "$msg"
}
function require_sysinfos() {
check_sysinfos "$@" && return 0
local -a infos; local info
for info in "$@"; do
if ! [[ "$info" == -* ]]; then
infos=("${infos[@]}" "$info")
fi
done
unsupported_system "${infos[@]}"
}
function on_debian() {
NUTOOLS_ON_DEBIAN=
if check_sysinfos -d debian; then
urequire debian
if [ $# -gt 0 ]; then
NUTOOLS_ON_DEBIAN=debian
"$@"
else
NUTOOLS_ON_DEBIAN=1
fi
return 0
else
return 1
fi
}
function on_debian:() { on_debian "$@"; }
function __on_debian() {
[ -z "$NUTOOLS_ON_DEBIAN" -o "$NUTOOLS_ON_DEBIAN" != 1 ] && return 1
local sysver="$1"; shift
if [ $# -gt 0 ]; then
if check_sysinfos -d debian -v "$sysver"; then
NUTOOLS_ON_DEBIAN="$sysver"
"$@"
return 0
else
return 1
fi
else
if check_sysinfos -d debian -v "$sysver+"; then
NUTOOLS_ON_DEBIAN="$sysver"
return 0
fi
fi
}
function on_stretch() { __on_debian stretch "$@"; }
function on_jessie() { __on_debian jessie "$@"; }
function on_wheezy() { __on_debian wheezy "$@"; }
function on_squeeze() { __on_debian squeeze "$@"; }
function on_default() {
if [ "$NUTOOLS_ON_DEBIAN" == 1 ]; then
if [ $# -gt 0 ]; then
"$@"
return 0
else
return 0
fi
elif [ -n "$NUTOOLS_ON_DEBIAN" ]; then
return 1
fi
return 1
}
function require_debian() {
set -- -d debian "$@"
if check_sysinfos "$@"; then
urequire debian
return 0
fi
local -a infos; local info
for info in "$@"; do
if ! [[ "$info" == -* ]]; then
infos=("${infos[@]}" "$info")
fi
done
local msg="Ce script n'est pas supporté sur $(get_sysinfos_desc)"
[ -n "$*" ] && msg="$msg
Il faut au moins l'un des systèmes suivants: ${infos[*]}"
[ -n "$UINST" -a -n "$ABORT" ] && touch "$ABORT"
die "$msg"
}
function require_stretch() {
require_debian -v stretch+
}
##@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
qvals "${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() {
if [ -n "$1" ]; then
echo "$1" | awk '{ print strftime("%-M %-H %-d %-m %u", $0) }'
else
awk 'BEGIN { print strftime("%-M %-H %-d %-m %u", systime()) }'
fi
}
__CTRESOLVE_CTNOW=""
function ctresolve() {
local -a ctnow
if [ "$__CTRESOLVE_CTNOW" == "**ANY**" ]; then
ctnow=("$__CTRESOLVE_CTNOW")
elif [ -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) {
if (refM == "**ANY**") return 1
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
}
CRONTAB_PREFIXES=(CRONTABDIR)
UTOOLS_PREFIXES=("${UTOOLS_PREFIXES[@]}" "${CRONTAB_PREFIXES[@]}")
function compute_crontab_prefixes() {
__compute_crontab_prefixes
}
function recompute_crontab_prefixes() {
local v
for v in "${CRONTAB_PREFIXES[@]}"; do
eval "$v="
done
__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=
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
undoscript="undo-ucrontab.sh"
fi
fi
function update_undoscript() {
local undoscript="$1" user="$2" host="$3" ctline="$4"
[ -n "$undoscript" ] || return
[ -n "$fake" ] && undoscript="fake-$undoscript"
[ -z "$fake" ] && estep "Maj de $undoscript"
if [ ! -f "$undoscript" ]; then
cat >"$undoscript" <<EOF
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 "$(qvals "${undocmd[@]}") || allok=" >>"$undoscript"
}
function get_time() {
awk '{print $2 ":" $1 }' <<<"$1"
}
function update_time() {
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))
fi
echo "$hours:$minutes"
}
function update_ctline() {
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() {
local ctline="$1" cmd="$2"
awkrun cmd="$cmd" '{$0 = $1 " " $2 " " $3 " " $4 " " $5 " " cmd; print}' <<<"$ctline"
}
function do_local() {
if [ "$user" != "root" -a "$user" == "$USER" ]; then
user=
fi
[ -n "$cmdfile" ] || cmdfile=custom-script
local r=0
local tmpcmd="$TMPDIR/ucrontab-$(basename "$cmdfile")"
if [ -n "$cmd" ]; then
echo "\
$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 $(qvals "$(update_cmd "$ctline" "$tmpcmd:")")
$(sed 's/^/ /g' <<<"$cmd")"
else
eecho "$action $(qvals "$ctline")"
fi
elif "$action" "$ctline" "$user"; then
estep "$action $ctline"
update_undoscript "$undoscript" "$user" "" "$ctline"
else
r=$?
if [ $r -eq 123 ]; then
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="$(qvals chmod +x "$remotename"); $(qvals "./$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 $(qvalm "$(update_cmd "$ctline" "$cmdfile:")")
$(sed 's/^/ /g' <<<"$cmd")"
else
eecho "[$host] $action $(qvalm "$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
}
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"
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
[ -n "$ctline" ] || ctline="$DEFAULT_CTLINE"
else
[ -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")"
[ "$increment" == "auto" ] && increment=
remotename="$scriptname.$$"
aoffset=0
if [ -n "$hostsfiles" ]; then
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
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
cmdfile="${2#<}"
cmd="$(<"$cmdfile")" || return 1
else
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
if [ -n "${hosts[*]}" ]; then
do_remote; exit $?
else
do_local; exit $?
fi
fi