#!/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 '&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() { = 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) 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 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 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 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/.*//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" <"$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