9141 lines
		
	
	
		
			250 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			9141 lines
		
	
	
		
			250 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | ||
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | ||
| #source "$(dirname -- "$0")/lib/ulib/ulib" || exit 1
 | ||
| #urequire DEFAULTS crontab
 | ||
| # Pour pouvoir être copié le cas échéant sur un hôte distant, la librairie ulib
 | ||
| # est inclue avec uinc à partir de lib/ulib. En mode développement, il faut
 | ||
| # replier les inclusions avec uinc -f et décommenter les lignes ci-dessus
 | ||
| 
 | ||
| function display_help() {
 | ||
|     uecho "$scriptname: Ajouter/Supprimer une ligne dans crontab
 | ||
| 
 | ||
| USAGE
 | ||
|     $scriptname [options] ctline
 | ||
| 
 | ||
| OPTIONS
 | ||
|     -a  Ajouter la ligne dans le fichier crontab (par défaut)
 | ||
|     -r  Enlever la ligne dans le fichier crontab
 | ||
|     -u user
 | ||
|         Spécifier l'utilisateur pour lequel on modifie crontab. Par défaut,
 | ||
|         modifier le crontab de root
 | ||
|     -H host:hosts...
 | ||
|         Modifier le crontab sur les hôtes distants spécifiés. Avec l'hôte '.' ou
 | ||
|         'localhost', la modification est faite sur l'hôte local
 | ||
|         Si l'action est -a, un script 'undo-ucrontab.sh' est créé dans le
 | ||
|         répertoire courant, qui annule la planification. Il est possible de
 | ||
|         lancer ce script le lendemain pour enlever les planifications
 | ||
|         installées.
 | ||
|     ctline
 | ||
|         Ligne de crontab de la forme 'minutes hours days months dows command'
 | ||
|         Si la ligne est de la forme halt[@hh:mm], la commande 'shutdown -h now'
 | ||
|         est planifiée pour le LENDEMAIN à hh:mm. si hh:mm n'est pas spécifié,
 | ||
|         l'arrêt est planifié pour 7:00
 | ||
|     -t hh:mm
 | ||
|         Ignorer la partie 'minutes hours days months dows' de ctline, et la
 | ||
|         remplacer par une planification à hh:mm le LENDEMAIN.
 | ||
|     --dom dayOfMonth
 | ||
|     --month month
 | ||
|         Spécifier respectivement le jour du mois et le mois (1-12) auquel faire
 | ||
|         la planification. Par défaut, les planifications sont effectuées pour le
 | ||
|         LENDEMAIN. Il est conseillé de spécifier les deux arguments si le jour
 | ||
|         doit être fixé.
 | ||
|     -s cmdfile
 | ||
|         Spécifier un fichier, dont le contenu est utilisé pour générer le script
 | ||
|         qui est planifié. Le fichier doit contenir l'ensemble des commandes à
 | ||
|         exécuter. Le script est modifié pour s'autodétruire à la fin de son
 | ||
|         exécution. Si ce comportement n'est pas souhaité, il faut rajouter la
 | ||
|         commande 'exit 0' à la fin.
 | ||
|     -S cmd
 | ||
|         Comme -s, mais spécifier le contenu du fichier directement sur la ligne
 | ||
|         de commande.
 | ||
|     -f hostsfile
 | ||
|         Spécifier un fichier qui contient la liste des hôtes sur lesquels faire
 | ||
|         les planifications.
 | ||
|         Les options -s, -S, -H, -d, -n sont ignorées. L'option --add est valide
 | ||
|         jusqu'au premier @group du fichier. Voici le format de ce fichier:
 | ||
| 
 | ||
|         Un groupe d'hôte débute par une ligne de la forme '@group:adelay:gdelay'
 | ||
|         - adelay est le nombre de minutes à laisser passer entre les hôtes du
 | ||
|           groupe (par défaut 1)
 | ||
|         - gdelay est le nombre de minutes à laisser passer après le traitement
 | ||
|           du groupe (par défaut 15)
 | ||
|         Les autres lignes sont des hôtes sur lequels planifier l'opération, de
 | ||
|         la forme 'host:cmd'
 | ||
|         - host est un nom d'hôte pleinement qualifié, sur lequel il est possible
 | ||
|           de se connecter par clé.
 | ||
|         - cmd est une description de la commande à lancer pour effectuer
 | ||
|           l'opération planifiée. Utiliser la syntaxe '<script' pour prendre le
 | ||
|           contenu du fichier de script spécifié. Le script est copié dans un
 | ||
|           fichier temporaire sur l'hôte, et se supprime après son
 | ||
|           lancement. Sinon, la commande spécifiée est utilisée telle quelle. Si
 | ||
|           cmd n'est pas spécifié, prendre la commande par défaut donnée par
 | ||
|           ctline
 | ||
|         Les lignes vides et commençant par '#' sont ignorées
 | ||
|         La commande '@include:file' permet d'inclure un autre fichier
 | ||
| 
 | ||
|     -d  Activer l'incrémentation automatique des heures de planification entre
 | ||
|         chaque hôte. Ceci permet par exemple de planifier l'arrêt d'un certain
 | ||
|         nombre de machines dans un ordre précis, en horaire décalé.
 | ||
|         Cette option est activée par défaut si ctline==halt[@time]
 | ||
|     -n  Désactiver l'incrémentation automatique des heures de planification.
 | ||
|     --add ADELAY
 | ||
|         Spécifier le nombre de minutes entre chaque hôte pour l'incrémentation
 | ||
|         automatique des heures de planification. Par défaut, il y a 1 minute
 | ||
|         entre chaque hôte.
 | ||
|     --us undo-script
 | ||
|         Spécifier le nom du script qui annule la planification. Utiliser \"\"
 | ||
|         pour désactiver cette fonctionnalité.
 | ||
|     --fake
 | ||
|         Afficher simplement les modifications qui doivent être effectuées."
 | ||
| }
 | ||
| 
 | ||
| DEFAULT_ADELAY=1
 | ||
| DEFAULT_GDELAY=15
 | ||
| 
 | ||
| ##@inc[base
 | ||
| ## Fonctions de base
 | ||
| ##@*inc[base.ulib
 | ||
| ## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
 | ||
| ## cas où cette librairie n'est pas chargée
 | ||
| if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
 | ||
|     ULIBPROVIDED=()
 | ||
|     function uprovided() {
 | ||
|         local module
 | ||
|         for module in "${ULIBPROVIDED[@]}"; do
 | ||
|             [ "$module" == "$1" ] && return 0
 | ||
|         done
 | ||
|         return 1
 | ||
|     }
 | ||
|     function uprovide() {
 | ||
|         uprovided "$1" && return 1
 | ||
|         ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
 | ||
|     }
 | ||
|     function urequire() {
 | ||
|         local module r=0
 | ||
|         for module in "$@"; do
 | ||
|             uprovided "$module" && continue
 | ||
|             echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
 | ||
|             r=1
 | ||
|         done
 | ||
|         return $r
 | ||
|     }
 | ||
|     uprovide base.ulib
 | ||
| fi
 | ||
| ##@*inc]base.ulib
 | ||
| ##@inc[base.init
 | ||
| ## Fonctions de base: initialisation de l'environnement
 | ||
| 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(/&/, "\\&", s)
 | ||
|   gsub(/"/, "\\"", s)
 | ||
|   gsub(/>/, "\\>", s)
 | ||
|   gsub(/</, "\\<", s)
 | ||
|   return s
 | ||
| }
 | ||
| function unquote_html(s) {
 | ||
|   gsub(/</, "<", s)
 | ||
|   gsub(/>/, ">", s)
 | ||
|   gsub(/"/, "\"", s)
 | ||
|   gsub(/&/, "\\&", 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
 |