diff --git a/CHANGES.txt b/CHANGES.txt index 0e0b436..8cb0f7f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +## Version 2.10.0 du 19/08/2015-10:23 + +6ba41b9 support de --uses-su pour ruinst -C + ## Version 2.9.0 du 10/08/2015-14:04 447d13f support de nouvelles versions d'OS pour sysinfos diff --git a/VERSION.txt b/VERSION.txt index c8e38b6..10c2c0c 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -2.9.0 +2.10.0 diff --git a/lib/ulib/support/install-pubkeys.sh b/lib/ulib/support/install-pubkeys.sh index e69de29..efe0c41 100755 --- a/lib/ulib/support/install-pubkeys.sh +++ b/lib/ulib/support/install-pubkeys.sh @@ -0,0 +1,6733 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +PUBKEYS="@@PUBKEYS@@" +[ "$PUBKEYS" != "@@""PUBKEYS""@@" ] || exit 1 + +##@inc[../base +## Fonctions de base +##@*inc[base.ulib +## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le +## cas où cette librairie n'est pas chargée +if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then + ULIBPROVIDED=() + function uprovided() { + local module + for module in "${ULIBPROVIDED[@]}"; do + [ "$module" == "$1" ] && return 0 + done + return 1 + } + function uprovide() { + uprovided "$1" && return 1 + ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1") + } + function urequire() { + local module r=0 + for module in "$@"; do + uprovided "$module" && continue + echo "error: $module: this module is required but cannot be automatically loaded" 1>&2 + r=1 + done + return $r + } + uprovide base.ulib +fi +##@*inc]base.ulib +##@inc[base.init +## Fonctions de base: initialisation de l'environnement +uprovide base.init + +if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then + : +elif [ "$0" == "-bash" ]; then + scriptname= + scriptdir= + script= +elif [ ! -f "$0" -a -f "${0#-}" ]; then + scriptname="$(basename -- "${0#-}")" + scriptdir="$(dirname -- "${0#-}")" + scriptdir="$(cd "$scriptdir"; pwd)" + script="$scriptdir/$scriptname" +else + scriptname="$(basename -- "$0")" + scriptdir="$(dirname -- "$0")" + scriptdir="$(cd "$scriptdir"; pwd)" + script="$scriptdir/$scriptname" +fi +: "${ULIBDIR:=$scriptdir}" + +[ -z "$TMPDIR" -a -d "$HOME/tmp" ] && TMPDIR="$HOME/tmp" +export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}" + +[ -z "$USER" -a -n "$LOGNAME" ] && export USER="$LOGNAME" + +[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc +[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc +true +##@inc]base.init +##@inc[base.core +## Fonctions de base: fondement +uprovide base.core + +function echo_() { + echo -n "$*" +} +function recho() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + local l="${#1}" + [ $l -eq 0 -o $l -gt 80 ] && return 0 + local s="${*//[a-zA-Z0-9]/}" + s="${s//,/}" + s="${s//./}" + s="${s//+/}" + s="${s//\//}" + s="${s//-/}" + s="${s//_/}" + s="${s//=/}" + [ -n "$s" ] +} +function qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + local arg first=1 + for arg in "$@"; do + [ -z "$first" ] && echo -n " " + if should_quote "$arg"; then + echo -n \" + _qval "$arg" + echo -n \" + else + recho_ "$arg" + fi + first= + done + [ -z "$first" ] && echo +} +function qwc() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + local r a b + while [ -n "$s" ]; do + if [[ "$s" == *\** ]]; then + if [[ "$s" == *\?* ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\**}" + s="${s#*\*}" + r="$r\"$a\"*" + fi + elif [[ "$s" == *\?* ]]; then + if [[ "$s" == *\** ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\?*}" + s="${s#*\?}" + r="$r\"$a\"?" + fi + else + r="$r\"$s\"" + break + 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 setx() { + if [ "$1" == -a ]; then + shift + local __s_array="$1"; shift + if [[ "$__s_array" == *=* ]]; then + set -- "${__s_array#*=}" "$@" + __s_array="${__s_array%%=*}" + fi + eval "$__s_array=($("$@" | qlines))" + else + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var="'"$("$@")"' + fi +} +function _setvx() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + local __e_val __e_arg __e_r=0 + local -a __e_cmd + + local __e_first=1 + while [ $# -gt 0 ]; do + __e_cmd=() + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + [ "$__e_arg" == // ] && break + if [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + continue + fi + fi + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + done + + if [ -n "$__e_first" ]; then + __e_val="$("${__e_cmd[@]}")" || __e_r=$? + else + __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? + fi + __e_first= + done + [ -n "$__e_val" ] && echo "$__e_val" + return $__e_r +} +function setxx() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalx "$@" +} +function evalp() { + local __e_arg __e_cmd + + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + if [ "$__e_arg" == // ]; then + __e_cmd="$__e_cmd |" + continue + elif [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + fi + fi + __e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\"" + done + eval "$__e_cmd" +} +function setxp() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.string +## Fonctions de base: gestion des valeurs scalaires +uprovide base.string +urequire base.core + +function straddp() { + local p="$1"; shift + echo "$p$*" +} +function strdelp() { + local p="$1"; shift + local str="$*" + echo "${str#$p}" +} +function strdelp2() { + local p="$1"; shift + local str="$*" + echo "${str##$p}" +} +function stradds() { + local s="$1"; shift + echo "$*$s" +} +function strdels() { + local s="$1"; shift + local str="$*" + echo "${str%$s}" +} +function strdels2() { + local s="$1"; shift + local str="$*" + echo "${str%%$s}" +} +function strlower() { + local str="$*" + echo "${str,,}" +} +function strlower1() { + local str="$*" + echo "${str,}" +} +function strlowers() { + local str="$*" + echo "${*,}" +} +function strupper() { + local str="$*" + echo "${str^^}" +} +function strupper1() { + local str="$*" + echo "${str^}" +} +function struppers() { + echo "${*^}" +} +function strmid() { + local range="$1"; shift + local str="$*" + if [[ "$range" == *:-* ]]; then + local max=${#str} + [ $max -eq 0 ] && return + local start="${range%%:*}" + [ -n "$start" ] || start=0 + while [ "$start" -lt 0 ]; do + start=$(($max$start)) + done + max=$(($max-$start)) + local length="${range#*:}" + while [ "$length" -lt 0 ]; do + length=$(($max$length)) + done + range="$start:$length" + fi + eval 'echo "${str:'" $range"'}"' +} +function strrepl() { + local pattern="$1"; shift + local repl="$1"; shift + local str="$*" + local cmd='echo "${str/' + if [ "${pattern#/}" != "$pattern" ]; then + pattern="${pattern#/}" + cmd="$cmd/" + elif [ "${pattern#\#}" != "$pattern" ]; then + pattern="${pattern#\#}" + cmd="$cmd#" + elif [ "${pattern#%}" != "$pattern" ]; then + pattern="${pattern#%}" + cmd="$cmd%" + fi + cmd="$cmd"'$pattern/$repl}"' + eval "$cmd" +} + +function first_char() { + local str="$*" + echo "${str:0:1}" +} +function last_char() { + local str="$*" + echo "${str: -1:1}" +} +function first_chars() { + local str="$*" + recho "${str:0:$((${#1}-1))}" +} +function last_chars() { + local str="$*" + recho "${str:1}" +} +function first_char_is() { + [ "${1:0:1}" == "$2" ] +} +function last_char_is() { + [ "${1:$((-1)):1}" == "$2" ] +} +function beginswith() { + local str="$1" pattern="$2" + eval '[ "${str#$pattern}" != "$str" ]' +} +function endswith() { + local str="$1" pattern="$2" + eval '[ "${str%$pattern}" != "$str" ]' +} +##@inc]base.string +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + +function is_yes() { + case "${1,,}" in + o|oui|y|yes|v|vrai|t|true|on) return 0;; + esac + isnum "$1" && [ "$1" -ne 0 ] && return 0 + return 1 +} +function is_no() { + case "${1,,}" in + n|non|no|f|faux|false|off) return 0;; + esac + isnum "$1" && [ "$1" -eq 0 ] && return 0 + return 1 +} +function yesval() { + is_yes "$1" && echo 1 +} + +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.array +## Fonctions de base: gestion des tableaux +uprovide base.array +urequire base.core +##@inc]base.array +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote +##@inc[base.split +## Fonctions de base: analyse et découpage de valeurs +uprovide base.split +urequire base.core + +function splitfsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitfsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitlsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitlsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitvar() { + splitfsep "$1" = "${2:-name}" "${3:-value}" +} +function 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 + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + local l="${#1}" + [ $l -eq 0 -o $l -gt 80 ] && return 0 + local s="${*//[a-zA-Z0-9]/}" + s="${s//,/}" + s="${s//./}" + s="${s//+/}" + s="${s//\//}" + s="${s//-/}" + s="${s//_/}" + s="${s//=/}" + [ -n "$s" ] +} +function qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + local arg first=1 + for arg in "$@"; do + [ -z "$first" ] && echo -n " " + if should_quote "$arg"; then + echo -n \" + _qval "$arg" + echo -n \" + else + recho_ "$arg" + fi + first= + done + [ -z "$first" ] && echo +} +function qwc() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + local r a b + while [ -n "$s" ]; do + if [[ "$s" == *\** ]]; then + if [[ "$s" == *\?* ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\**}" + s="${s#*\*}" + r="$r\"$a\"*" + fi + elif [[ "$s" == *\?* ]]; then + if [[ "$s" == *\** ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\?*}" + s="${s#*\?}" + r="$r\"$a\"?" + fi + else + r="$r\"$s\"" + break + 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 setx() { + if [ "$1" == -a ]; then + shift + local __s_array="$1"; shift + if [[ "$__s_array" == *=* ]]; then + set -- "${__s_array#*=}" "$@" + __s_array="${__s_array%%=*}" + fi + eval "$__s_array=($("$@" | qlines))" + else + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var="'"$("$@")"' + fi +} +function _setvx() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + local __e_val __e_arg __e_r=0 + local -a __e_cmd + + local __e_first=1 + while [ $# -gt 0 ]; do + __e_cmd=() + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + [ "$__e_arg" == // ] && break + if [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + continue + fi + fi + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + done + + if [ -n "$__e_first" ]; then + __e_val="$("${__e_cmd[@]}")" || __e_r=$? + else + __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? + fi + __e_first= + done + [ -n "$__e_val" ] && echo "$__e_val" + return $__e_r +} +function setxx() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalx "$@" +} +function evalp() { + local __e_arg __e_cmd + + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + if [ "$__e_arg" == // ]; then + __e_cmd="$__e_cmd |" + continue + elif [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + fi + fi + __e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\"" + done + eval "$__e_cmd" +} +function setxp() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.string +## Fonctions de base: gestion des valeurs scalaires +uprovide base.string +urequire base.core + +function straddp() { + local p="$1"; shift + echo "$p$*" +} +function strdelp() { + local p="$1"; shift + local str="$*" + echo "${str#$p}" +} +function strdelp2() { + local p="$1"; shift + local str="$*" + echo "${str##$p}" +} +function stradds() { + local s="$1"; shift + echo "$*$s" +} +function strdels() { + local s="$1"; shift + local str="$*" + echo "${str%$s}" +} +function strdels2() { + local s="$1"; shift + local str="$*" + echo "${str%%$s}" +} +function strlower() { + local str="$*" + echo "${str,,}" +} +function strlower1() { + local str="$*" + echo "${str,}" +} +function strlowers() { + local str="$*" + echo "${*,}" +} +function strupper() { + local str="$*" + echo "${str^^}" +} +function strupper1() { + local str="$*" + echo "${str^}" +} +function struppers() { + echo "${*^}" +} +function strmid() { + local range="$1"; shift + local str="$*" + if [[ "$range" == *:-* ]]; then + local max=${#str} + [ $max -eq 0 ] && return + local start="${range%%:*}" + [ -n "$start" ] || start=0 + while [ "$start" -lt 0 ]; do + start=$(($max$start)) + done + max=$(($max-$start)) + local length="${range#*:}" + while [ "$length" -lt 0 ]; do + length=$(($max$length)) + done + range="$start:$length" + fi + eval 'echo "${str:'" $range"'}"' +} +function strrepl() { + local pattern="$1"; shift + local repl="$1"; shift + local str="$*" + local cmd='echo "${str/' + if [ "${pattern#/}" != "$pattern" ]; then + pattern="${pattern#/}" + cmd="$cmd/" + elif [ "${pattern#\#}" != "$pattern" ]; then + pattern="${pattern#\#}" + cmd="$cmd#" + elif [ "${pattern#%}" != "$pattern" ]; then + pattern="${pattern#%}" + cmd="$cmd%" + fi + cmd="$cmd"'$pattern/$repl}"' + eval "$cmd" +} + +function first_char() { + local str="$*" + echo "${str:0:1}" +} +function last_char() { + local str="$*" + echo "${str: -1:1}" +} +function first_chars() { + local str="$*" + recho "${str:0:$((${#1}-1))}" +} +function last_chars() { + local str="$*" + recho "${str:1}" +} +function first_char_is() { + [ "${1:0:1}" == "$2" ] +} +function last_char_is() { + [ "${1:$((-1)):1}" == "$2" ] +} +function beginswith() { + local str="$1" pattern="$2" + eval '[ "${str#$pattern}" != "$str" ]' +} +function endswith() { + local str="$1" pattern="$2" + eval '[ "${str%$pattern}" != "$str" ]' +} +##@inc]base.string +##@inc[base.array +## Fonctions de base: gestion des tableaux +uprovide base.array +urequire base.core +##@inc]base.array +uprovide base.args +urequire base.core base.string base.array #XXX maj de cette liste + +function __po_parse_optdescs() { + local -a optdescs_ + local optdesc_ option_ name_ flag_ value_ + local reset_ + local shift_ + local i_ count_ + + let shift_=0 + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + let shift_=$shift_+1 + break + elif [ "$1" == "%" ]; then + reset_=1 + shift + let shift_=$shift_+1 + elif [ "$1" == "-" -o "$1" == "+" ]; then + if [ "${opts_#+}" != "$opts_" ]; then + opts_="${opts_#+}" + elif [ "${opts_#-}" != "$opts_" ]; then + opts_="${opts_#-}" + fi + opts_="$1$opts_" + shift + let shift_=$shift_+1 + elif [ "$1" == "@" ]; then + destargs_="$2" + shift; shift + let shift_=$shift_+2 + elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then + array_split optdescs_ "$1" "," + if [ "$2" == . ]; then + local autoname_= + for optdesc_ in "${optdescs_[@]}"; do + if [ ${#optdesc_} -gt ${#autoname_} ]; then + autoname_="$optdesc_" + fi + done + while [ -n "$autoname_" -a "${autoname_#-}" != "$autoname_" ]; do autoname_="${autoname_#-}"; done + while [ -n "$autoname_" -a "${autoname_%:}" != "$autoname_" ]; do autoname_="${autoname_%:}"; done + autoname_="${autoname_//-/_}" + shift; shift + set -- dummy "$autoname_" "$@" + fi + for optdesc_ in "${optdescs_[@]}"; do + if [[ "$2" == \$* ]]; then + name_="$2" + if [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + flag_='::$' + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + flag_=':$' + else + option_="$optdesc_" + flag_='$' + fi + elif [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=:: + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=: + else + option_="$optdesc_" + name_="$2" + [ -n "$reset_" ] && eval "$name_=" + flag_= + fi + + if i_="$(array_find options_ "$option_")"; then + options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") + names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") + flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") + fi + options_=("${options_[@]}" "$option_") + names_=("${names_[@]}" "$name_") + flags_=("${flags_[@]}" "$flag_") + done + shift; shift + let shift_=$shift_+2 + else + break + fi + done + + i_=0 + count_=${#options_[*]} + while [ $i_ -lt $count_ ]; do + option_="${options_[$i_]}" + flag_="${flags_[$i_]}" + i_=$(($i_ + 1)) + + flag_="${flag_%$}" + if [[ "$option_" == --* ]]; then + longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" + elif [[ "$option_" == -* ]]; then + opts_="$opts_${option_#-}$flag_" + fi + done + + return $shift_ +} +function __po_check_options() { + local -a getopt_args_ + getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") + local args_ + if args_="$(getopt -q "${getopt_args_[@]}")"; then + recho "$args_" + return 0 + else + LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null + return 1 + fi +} +function __po_process_options() { + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + break + elif [[ "$1" == -* ]]; then + local i_ + let i_=0 + for option_ in "${options_[@]}"; do + [ "$1" == "${options_[$i_]}" ] && break + let i_=$i_+1 + done + name_="names_[$i_]"; name_="${!name_}" + flag_="flags_[$i_]"; flag_="${!flag_}" + function inc@ { eval "let $1=\$$1+1"; } + function res@ { 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() { + + + + 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_" + return 1 + fi +} + +function parse_args_check() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0 + eerror "$args" + return 1 +} +function parse_args() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args" +} + +HELP_DESC= +HELP_USAGE= +HELP_OPTIONS= +function __genparse_shortopt() { + local LC_COLLATE=C + local shortopt="${1//[^A-Z]}" + shortopt="$(strlower "${shortopt:0:1}")" + [ -n "$shortopt" ] && echo "$shortopt" +} +function genparse() { + + local -a names descs vars options + local i desc var option name uname value shortopt + + for var in "$@"; do + if [[ "$var" == *=* ]]; then + splitvar "$var" name value + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option VALUE" + array_add vars "$(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 + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + local l="${#1}" + [ $l -eq 0 -o $l -gt 80 ] && return 0 + local s="${*//[a-zA-Z0-9]/}" + s="${s//,/}" + s="${s//./}" + s="${s//+/}" + s="${s//\//}" + s="${s//-/}" + s="${s//_/}" + s="${s//=/}" + [ -n "$s" ] +} +function qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + local arg first=1 + for arg in "$@"; do + [ -z "$first" ] && echo -n " " + if should_quote "$arg"; then + echo -n \" + _qval "$arg" + echo -n \" + else + recho_ "$arg" + fi + first= + done + [ -z "$first" ] && echo +} +function qwc() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + local r a b + while [ -n "$s" ]; do + if [[ "$s" == *\** ]]; then + if [[ "$s" == *\?* ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\**}" + s="${s#*\*}" + r="$r\"$a\"*" + fi + elif [[ "$s" == *\?* ]]; then + if [[ "$s" == *\** ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\?*}" + s="${s#*\?}" + r="$r\"$a\"?" + fi + else + r="$r\"$s\"" + break + 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 setx() { + if [ "$1" == -a ]; then + shift + local __s_array="$1"; shift + if [[ "$__s_array" == *=* ]]; then + set -- "${__s_array#*=}" "$@" + __s_array="${__s_array%%=*}" + fi + eval "$__s_array=($("$@" | qlines))" + else + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var="'"$("$@")"' + fi +} +function _setvx() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + local __e_val __e_arg __e_r=0 + local -a __e_cmd + + local __e_first=1 + while [ $# -gt 0 ]; do + __e_cmd=() + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + [ "$__e_arg" == // ] && break + if [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + continue + fi + fi + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + done + + if [ -n "$__e_first" ]; then + __e_val="$("${__e_cmd[@]}")" || __e_r=$? + else + __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? + fi + __e_first= + done + [ -n "$__e_val" ] && echo "$__e_val" + return $__e_r +} +function setxx() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalx "$@" +} +function evalp() { + local __e_arg __e_cmd + + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + if [ "$__e_arg" == // ]; then + __e_cmd="$__e_cmd |" + continue + elif [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + fi + fi + __e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\"" + done + eval "$__e_cmd" +} +function setxp() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.string +## Fonctions de base: gestion des valeurs scalaires +uprovide base.string +urequire base.core + +function straddp() { + local p="$1"; shift + echo "$p$*" +} +function strdelp() { + local p="$1"; shift + local str="$*" + echo "${str#$p}" +} +function strdelp2() { + local p="$1"; shift + local str="$*" + echo "${str##$p}" +} +function stradds() { + local s="$1"; shift + echo "$*$s" +} +function strdels() { + local s="$1"; shift + local str="$*" + echo "${str%$s}" +} +function strdels2() { + local s="$1"; shift + local str="$*" + echo "${str%%$s}" +} +function strlower() { + local str="$*" + echo "${str,,}" +} +function strlower1() { + local str="$*" + echo "${str,}" +} +function strlowers() { + local str="$*" + echo "${*,}" +} +function strupper() { + local str="$*" + echo "${str^^}" +} +function strupper1() { + local str="$*" + echo "${str^}" +} +function struppers() { + echo "${*^}" +} +function strmid() { + local range="$1"; shift + local str="$*" + if [[ "$range" == *:-* ]]; then + local max=${#str} + [ $max -eq 0 ] && return + local start="${range%%:*}" + [ -n "$start" ] || start=0 + while [ "$start" -lt 0 ]; do + start=$(($max$start)) + done + max=$(($max-$start)) + local length="${range#*:}" + while [ "$length" -lt 0 ]; do + length=$(($max$length)) + done + range="$start:$length" + fi + eval 'echo "${str:'" $range"'}"' +} +function strrepl() { + local pattern="$1"; shift + local repl="$1"; shift + local str="$*" + local cmd='echo "${str/' + if [ "${pattern#/}" != "$pattern" ]; then + pattern="${pattern#/}" + cmd="$cmd/" + elif [ "${pattern#\#}" != "$pattern" ]; then + pattern="${pattern#\#}" + cmd="$cmd#" + elif [ "${pattern#%}" != "$pattern" ]; then + pattern="${pattern#%}" + cmd="$cmd%" + fi + cmd="$cmd"'$pattern/$repl}"' + eval "$cmd" +} + +function first_char() { + local str="$*" + echo "${str:0:1}" +} +function last_char() { + local str="$*" + echo "${str: -1:1}" +} +function first_chars() { + local str="$*" + recho "${str:0:$((${#1}-1))}" +} +function last_chars() { + local str="$*" + recho "${str:1}" +} +function first_char_is() { + [ "${1:0:1}" == "$2" ] +} +function last_char_is() { + [ "${1:$((-1)):1}" == "$2" ] +} +function beginswith() { + local str="$1" pattern="$2" + eval '[ "${str#$pattern}" != "$str" ]' +} +function endswith() { + local str="$1" pattern="$2" + eval '[ "${str%$pattern}" != "$str" ]' +} +##@inc]base.string +##@inc[base.array +## Fonctions de base: gestion des tableaux +uprovide base.array +urequire base.core +##@inc]base.array +uprovide base.args +urequire base.core base.string base.array #XXX maj de cette liste + +function __po_parse_optdescs() { + local -a optdescs_ + local optdesc_ option_ name_ flag_ value_ + local reset_ + local shift_ + local i_ count_ + + let shift_=0 + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + let shift_=$shift_+1 + break + elif [ "$1" == "%" ]; then + reset_=1 + shift + let shift_=$shift_+1 + elif [ "$1" == "-" -o "$1" == "+" ]; then + if [ "${opts_#+}" != "$opts_" ]; then + opts_="${opts_#+}" + elif [ "${opts_#-}" != "$opts_" ]; then + opts_="${opts_#-}" + fi + opts_="$1$opts_" + shift + let shift_=$shift_+1 + elif [ "$1" == "@" ]; then + destargs_="$2" + shift; shift + let shift_=$shift_+2 + elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then + array_split optdescs_ "$1" "," + if [ "$2" == . ]; then + local autoname_= + for optdesc_ in "${optdescs_[@]}"; do + if [ ${#optdesc_} -gt ${#autoname_} ]; then + autoname_="$optdesc_" + fi + done + while [ -n "$autoname_" -a "${autoname_#-}" != "$autoname_" ]; do autoname_="${autoname_#-}"; done + while [ -n "$autoname_" -a "${autoname_%:}" != "$autoname_" ]; do autoname_="${autoname_%:}"; done + autoname_="${autoname_//-/_}" + shift; shift + set -- dummy "$autoname_" "$@" + fi + for optdesc_ in "${optdescs_[@]}"; do + if [[ "$2" == \$* ]]; then + name_="$2" + if [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + flag_='::$' + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + flag_=':$' + else + option_="$optdesc_" + flag_='$' + fi + elif [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=:: + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=: + else + option_="$optdesc_" + name_="$2" + [ -n "$reset_" ] && eval "$name_=" + flag_= + fi + + if i_="$(array_find options_ "$option_")"; then + options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") + names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") + flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") + fi + options_=("${options_[@]}" "$option_") + names_=("${names_[@]}" "$name_") + flags_=("${flags_[@]}" "$flag_") + done + shift; shift + let shift_=$shift_+2 + else + break + fi + done + + i_=0 + count_=${#options_[*]} + while [ $i_ -lt $count_ ]; do + option_="${options_[$i_]}" + flag_="${flags_[$i_]}" + i_=$(($i_ + 1)) + + flag_="${flag_%$}" + if [[ "$option_" == --* ]]; then + longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" + elif [[ "$option_" == -* ]]; then + opts_="$opts_${option_#-}$flag_" + fi + done + + return $shift_ +} +function __po_check_options() { + local -a getopt_args_ + getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") + local args_ + if args_="$(getopt -q "${getopt_args_[@]}")"; then + recho "$args_" + return 0 + else + LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null + return 1 + fi +} +function __po_process_options() { + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + break + elif [[ "$1" == -* ]]; then + local i_ + let i_=0 + for option_ in "${options_[@]}"; do + [ "$1" == "${options_[$i_]}" ] && break + let i_=$i_+1 + done + name_="names_[$i_]"; name_="${!name_}" + flag_="flags_[$i_]"; flag_="${!flag_}" + function inc@ { eval "let $1=\$$1+1"; } + function res@ { 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() { + + + + 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_" + return 1 + fi +} + +function parse_args_check() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0 + eerror "$args" + return 1 +} +function parse_args() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args" +} + +HELP_DESC= +HELP_USAGE= +HELP_OPTIONS= +function __genparse_shortopt() { + local LC_COLLATE=C + local shortopt="${1//[^A-Z]}" + shortopt="$(strlower "${shortopt:0:1}")" + [ -n "$shortopt" ] && echo "$shortopt" +} +function genparse() { + + local -a names descs vars options + local i desc var option name uname value shortopt + + for var in "$@"; do + if [[ "$var" == *=* ]]; then + splitvar "$var" name value + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option VALUE" + array_add vars "$(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 + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + local l="${#1}" + [ $l -eq 0 -o $l -gt 80 ] && return 0 + local s="${*//[a-zA-Z0-9]/}" + s="${s//,/}" + s="${s//./}" + s="${s//+/}" + s="${s//\//}" + s="${s//-/}" + s="${s//_/}" + s="${s//=/}" + [ -n "$s" ] +} +function qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + local arg first=1 + for arg in "$@"; do + [ -z "$first" ] && echo -n " " + if should_quote "$arg"; then + echo -n \" + _qval "$arg" + echo -n \" + else + recho_ "$arg" + fi + first= + done + [ -z "$first" ] && echo +} +function qwc() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + local r a b + while [ -n "$s" ]; do + if [[ "$s" == *\** ]]; then + if [[ "$s" == *\?* ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\**}" + s="${s#*\*}" + r="$r\"$a\"*" + fi + elif [[ "$s" == *\?* ]]; then + if [[ "$s" == *\** ]]; then + a="${s%%\**}" + b="${s%%\?*}" + if [ ${#a} -lt ${#b} ]; then + s="${s#*\*}" + r="$r\"$a\"*" + else + s="${s#*\?}" + r="$r\"$b\"?" + fi + else + a="${s%%\?*}" + s="${s#*\?}" + r="$r\"$a\"?" + fi + else + r="$r\"$s\"" + break + 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 setx() { + if [ "$1" == -a ]; then + shift + local __s_array="$1"; shift + if [[ "$__s_array" == *=* ]]; then + set -- "${__s_array#*=}" "$@" + __s_array="${__s_array%%=*}" + fi + eval "$__s_array=($("$@" | qlines))" + else + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var="'"$("$@")"' + fi +} +function _setvx() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + local __e_val __e_arg __e_r=0 + local -a __e_cmd + + local __e_first=1 + while [ $# -gt 0 ]; do + __e_cmd=() + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + [ "$__e_arg" == // ] && break + if [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + continue + fi + fi + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + done + + if [ -n "$__e_first" ]; then + __e_val="$("${__e_cmd[@]}")" || __e_r=$? + else + __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? + fi + __e_first= + done + [ -n "$__e_val" ] && echo "$__e_val" + return $__e_r +} +function setxx() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalx "$@" +} +function evalp() { + local __e_arg __e_cmd + + while [ $# -gt 0 ]; do + __e_arg="$1"; shift + if [ "$__e_arg" == // ]; then + __e_cmd="$__e_cmd |" + continue + elif [ "${__e_arg%//}" != "$__e_arg" ]; then + local __e_tmp="${__e_arg%//}" + if [ -z "${__e_tmp//\\/}" ]; then + __e_arg="${__e_arg#\\}" + fi + fi + __e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\"" + done + eval "$__e_cmd" +} +function setxp() { + local -a __s_args + if [ "$1" == -a ]; then __s_args=(-a); shift; fi + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + __s_args=("${__s_args[@]}" "$__s_var") + setx "${__s_args[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + +function is_yes() { + case "${1,,}" in + o|oui|y|yes|v|vrai|t|true|on) return 0;; + esac + isnum "$1" && [ "$1" -ne 0 ] && return 0 + return 1 +} +function is_no() { + case "${1,,}" in + n|non|no|f|faux|false|off) return 0;; + esac + isnum "$1" && [ "$1" -eq 0 ] && return 0 + return 1 +} +function yesval() { + is_yes "$1" && echo 1 +} + +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote +uprovide base.compat +urequire base.core base.num base.bool base.quote + + +function setx2() { setxx "$@"; } +function rawecho() { recho "$@"; } +function rawecho_() { recho_ "$@"; } +function quote_arg() { _qval "$@"; } +function quoted_arg() { qvalm "$@"; } +function quoted_args() { qvals "$@"; } +function set_var() { setv "$@"; } +function set_var_cmd() { echo_setv "$@"; } +function set_var_literal() { eval "$1=$2"; } + +function quote_awk() { _qawk "$@"; } +function quoted_awk() { qawk "$@"; } +function quote_seds() { qseds "$@"; } +function quote_form() { _qform "$@"; } +function quoted_form() { qform "$@"; } + + +if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then + function strlower() { tr A-Z a-z <<<"$*"; } + function strlower1() { + local str="$*" + local h="${str:0:1}" r="${str:1}" + echo "$(tr A-Z a-z <<<"$h")$r" + } + function strlowers() { + local -a vs; local v + for v in "$@"; do + vs=("${vs[@]}" "$(strlower1 "$v")") + done + echo "${vs[*]}" + } + function strupper() { tr a-z A-Z <<<"$*"; } + function strupper1() { + local str="$*" + local h="${str:0:1}" r="${str:1}" + echo "$(tr a-z A-Z <<<"$h")$r" + } + function struppers() { + local -a vs; local v + for v in "$@"; do + vs=("${vs[@]}" "$(strupper1 "$v")") + done + echo "${vs[*]}" + } + + function is_yes() { + case "$1" in + o|oui|y|yes|v|vrai|t|true|on) return 0;; + O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;; + esac + isnum "$1" && [ "$1" -ne 0 ] && return 0 + case "$(strlower "$1")" in + o|oui|y|yes|v|vrai|t|true|on) return 0;; + esac + return 1 + } + function is_no() { + case "$1" in + n|non|no|f|faux|false|off) return 0;; + N|NON|NO|F|FAUX|FALSE|OFF) return 0;; + esac + isnum "$1" && [ "$1" -eq 0 ] && return 0 + case "$(strlower "$1")" in + n|non|no|f|faux|false|off) return 0;; + esac + return 1 + } +fi +##@inc]base.compat +uprovide base +urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.tools base.compat + +UNAME_SYSTEM=`uname -s` +[ "${UNAME_SYSTEM#CYGWIN}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Cygwin +[ "${UNAME_SYSTEM#MINGW32}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Mingw +UNAME_MACHINE=`uname -m` +if [ -n "$UTOOLS_CHROOT" ]; then + [ -n "$UTOOLS_UNAME_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM" + [ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE" +fi + +function setyesval() { + is_yes "$2" && set_var "$1" 1 || set_var "$1" "" +} +function normyesval() { + is_yes "${2:-"${!1}"}" && set_var "$1" 1 || set_var "$1" "" +} +function normyesvals() { + local __nyv_yesvar + for __nyv_yesvar in "$@"; do + is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" "" + done +} +function quote_in() { + sed 's/\\/\\\\/g +s/"/\\"/g +s/\$/\\$/g +s/`/\\`/g' +} +function quote_sin() { + sed "s/'/'\\\\''/g" +} +function quote_sarg() { + quote_sin <<<"$1" +} +function quoted_sarg() { + echo "'$(quote_sarg "$1")'" +} +function quoted_sargs() { + local a s + for a in "$@"; do + s="${s:+$s }$(quoted_sarg "$a")" + done + rawecho "$s" +} + +function set_array_cmd() { + [ $# -eq 1 ] && set -- "$1" "$1" + local __sac_s __sac_v __sac_f + __sac_s="$1=("; shift + if [ "$1" == "@" ]; then + shift + else + eval "set -- \"\${$1[@]}\"" + fi + __sac_f=1 + for __sac_v in "$@"; do + [ -n "$__sac_f" ] && __sac_f= || __sac_s="$__sac_s " + __sac_s="$__sac_s$(quoted_arg "$__sac_v")" + done + __sac_s="$__sac_s)" + echo "$__sac_s" +} +function set_array() { + eval "$(set_array_cmd "$@")" +} +function array_count() { + eval "echo \${#$1[*]}" +} +function array_isempty() { + [ $(array_count "$1") -eq 0 ] +} +function array_new() { + eval "$1=()" +} +function array_add() { + local __aa_a="$1"; shift + eval "$__aa_a=(\"\${$__aa_a[@]}\" \"\$@\")" +} +function array_ins() { + local __aa_a="$1"; shift + eval "$__aa_a=(\"\$@\" \"\${$__aa_a[@]}\")" +} +function array_del() { + local __ad_v + local -a __ad_vs + eval 'for __ad_v in "${'"$1"'[@]}"; do + if [ "$__ad_v" != '"$(quoted_arg "$2")"' ]; then + array_add __ad_vs "$__ad_v" + fi +done' + array_copy "$1" __ad_vs +} +function array_addu() { + local __as_v + eval 'for __as_v in "${'"$1"'[@]}"; do + if [ "$__as_v" == '"$(quoted_arg "$2")"' ]; then + return 1 + fi +done' + array_add "$1" "$2" + return 0 +} +function array_set() { + array_addu "$@" +} +function array_insu() { + local __as_v + eval 'for __as_v in "${'"$1"'[@]}"; do + if [ "$__as_v" == '"$(quoted_arg "$2")"' ]; then + return 1 + fi +done' + array_ins "$1" "$2" + return 0 +} +function array_fillrange() { + local -a __af_vs + local __af_i="${2:-1}" __af_to="${3:-10}" __af_step="${4:-1}" + while [ "$__af_i" -le "$__af_to" ]; do + __af_vs=("${__af_vs[@]}" "$__af_i") + __af_i=$(($__af_i + $__af_step)) + done + array_copy "$1" __af_vs +} +function array_eq() { + local -a __ae_a1 __ae_a2 + array_copy __ae_a1 "$1" + array_copy __ae_a2 "$2" + [ ${#__ae_a1[*]} -eq ${#__ae_a2[*]} ] || return 1 + local __ae_v __ae_i=0 + for __ae_v in "${__ae_a1[@]}"; do + [ "$__ae_v" == "${__ae_a2[$__ae_i]}" ] || return 1 + __ae_i=$(($__ae_i + 1)) + done + return 0 +} +function array_contains() { + local __ac_v + eval 'for __ac_v in "${'"$1"'[@]}"; do + if [ "$__ac_v" == '"$(quoted_arg "$2")"' ]; then + return 0 + fi +done' + return 1 +} +function array_icontains() { + local __ac_v + eval 'for __ac_v in "${'"$1"'[@]}"; do + if [ "$(strlower "$__ac_v")" == '"$(strlower "$(quoted_arg "$2")")"' ]; then + return 0 + fi +done' + return 1 +} +function array_find() { + local __af_i __af_v + __af_i=0 + eval 'for __af_v in "${'"$1"'[@]}"; do + if [ "$__af_v" == '"$(quoted_arg "$2")"' ]; then + if [ -n "$3" ]; then + echo "${'"$3"'[$__af_i]}" + else + echo "$__af_i" + fi + return 0 + fi + __af_i=$(($__af_i + 1)) +done' + return 1 +} +function array_reverse() { + local -a __ar_vs + local __ar_v + array_copy __ar_vs "$1" + array_new "$1" + for __ar_v in "${__ar_vs[@]}"; do + array_ins "$1" "$__ar_v" + done +} + +function array_replace() { + local __ar_sn="$1"; shift + local __ar_f="$1"; shift + local -a __ar_s __ar_d + local __ar_v + array_copy __ar_s "$__ar_sn" + for __ar_v in "${__ar_s[@]}"; do + if [ "$__ar_v" == "$__ar_f" ]; then + __ar_d=("${__ar_d[@]}" "$@") + else + __ar_d=("${__ar_d[@]}" "$__ar_v") + fi + done + array_copy "$__ar_sn" __ar_d +} +function array_each() { + local __ae_an="$1"; shift + local __ae_f="$1"; shift + local -a __ae_a + local __ae_v + array_copy __ae_a "$__ae_an" + for __ae_v in "${__ae_a[@]}"; do + "$__ae_f" "$__ae_v" "$@" + done +} +function array_map() { + local __am_an="$1"; shift + local __am_f="$1"; shift + local -a __am_a __am_vs + local __am_v + array_copy __am_a "$__am_an" + for __am_v in "${__am_a[@]}"; do + __am_vs=("${__am_vs[@]}" "$("$__am_f" "$__am_v" "$@")") + done + array_copy "$__am_an" __am_vs +} +function first_value() { + eval "rawecho \"\${$1[@]:0:1}\"" +} +function last_value() { + eval "rawecho \"\${$1[@]:\$((-1)):1}\"" +} +function array_copy() { + eval "$1=(\"\${$2[@]}\")" +} +function array_copy_firsts() { + eval "$1=(\"\${${2:-$1}[@]:0:\$((\${#${2:-$1}[@]}-1))}\")" +} +function array_del_last() { + array_copy_firsts "$1" +} +function array_copy_lasts() { + eval "$1=(\"\${${2:-$1}[@]:1}\")" +} +function array_del_first() { + array_copy_lasts "$1" +} +function array_extend() { + eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")" +} +function array_extendu() { + local __ae_v __ae_s=1 + eval 'for __ae_v in "${'"$2"'[@]}"; do + array_addu "$1" "$__ae_v" && __ae_s=0 +done' + return "$__ae_s" +} +function array_extend_firsts() { + eval "$1=(\"\${$1[@]}\" \"\${$2[@]:0:\$((\${#$2[@]}-1))}\")" +} +function array_extend_lasts() { + eval "$1=(\"\${$1[@]}\" \"\${$2[@]:1}\")" +} +function array_xsplit() { + eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" ' +{ + gsub(/'\''/, "'\'\\\\\'\''") + print "'\''" $0 "'\''" +}'))" #" +} +function array_split() { + eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" ' +/^$/ { next } +{ + gsub(/'\''/, "'\'\\\\\'\''") + print "'\''" $0 "'\''" +}'))" #" +} +function array_from_path() { + array_split "$1" "$2" ":" +} +function array_from_xlines() { + eval "$1=($(recho_ "$2" | _nl2lf | awk ' +{ + gsub(/'\''/, "'\'\\\\\'\''") + print "'\''" $0 "'\''" +}'))" #" +} +function array_from_lines() { + eval "$1=($(recho_ "$2" | _nl2lf | awk ' +/^$/ { next } +{ + gsub(/'\''/, "'\'\\\\\'\''") + print "'\''" $0 "'\''" +}'))" #" +} +function array_join() { + local __aj_an __aj_l __aj_j __aj_s="${2:-,}" __aj_pf __aj_sf + if [ "$1" == "@" ]; then + __aj_an="\$@" + shift; shift + else + __aj_an="\${$1[@]}" + __aj_pf="$4" + __aj_sf="$5" + fi + eval 'for __aj_l in "'"$__aj_an"'"; do + __aj_j="${__aj_j:+$__aj_j'"$__aj_s"'}$__aj_pf$__aj_l$__aj_sf" +done' + if [ -n "$__aj_j" ]; then + rawecho "$__aj_j" + elif [ "$__aj_an" != "\$@" -a -n "$3" ]; then + rawecho "$3" + fi +} +function array_mapjoin() { + local __amj_src="$1" __amj_func="$2" __amj_sep="$3" + shift; shift; shift + if [ "$__amj_src" == "@" ]; then + local -a __amj_tmpsrc + __amj_tmpsrc=("$@") + __amj_src=__amj_tmpsrc + set -- + fi + local -a __amj_tmp + array_copy __amj_tmp "$__amj_src" + array_map __amj_tmp "$__amj_func" + array_join __amj_tmp "$__amj_sep" "$@" +} +function array_to_lines() { + array_join "$1" " +" "$2" "$3" "$4" +} +function array_to_path() { + array_join "$1" ":" "$2" "$3" "$4" +} +function array_fix_paths() { + local __afp_an="$1" __afp_s="${2:-:}" + local -a __afp_vs + local __afp_v + array_copy __afp_vs "$__afp_an" + array_new "$__afp_an" + for __afp_v in "${__afp_vs[@]}"; do + array_split __afp_v "$__afp_v" "$__afp_s" + array_extend "$__afp_an" __afp_v + done +} + + +function get_date_rfc822() { + LC_TIME=C date +"%a, %d %b %Y %H:%M:%S %Z" +} +function get_date_fr() { + LC_TIME=C date +"%d/%m/%Y" +} +function get_time_fr() { + LC_TIME=C date +"%Hh%M" +} +function parse_date() { + local value="$1" type="${2:-date}" + local now="$(awk 'BEGIN { print mktime(strftime("%Y %m %d 00 00 00 +0400")) }')" + case "$value" in + +*) + value="$(($now + ${value#+} * 86400))" + ;; + *) + value="$(<<<"$value" awk -F/ '{ + nd = strftime("%d"); nm = strftime("%m"); ny = strftime("%Y") + d = $1 + 0; if (d < 1) d = nd; + m = $2 + 0; if (m < 1) m = nm; + if ($3 == "") y = ny; + else { y = $3 + 0; if (y < 100) y = y + 2000; } + print mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d)); + }')" + esac + case "$type" in + d|date) awk '{ print strftime("%d/%m/%Y", $0 + 0) }' <<<"$value";; + l|ldap) awk '{ print strftime("%Y%m%d%H%M%S+0400", $0 + 0) }' <<<"$value";; + m|mysql) awk '{ print strftime("%Y-%m-%d", $0 + 0) }' <<<"$value";; + *) + rawecho "$value" + ;; + esac +} + + +function udelpath() { + local _qdir="${1//\//\\/}" + eval "export ${2:-PATH}; ${2:-PATH}"'="${'"${2:-PATH}"'#$1:}"; '"${2:-PATH}"'="${'"${2:-PATH}"'%:$1}"; '"${2:-PATH}"'="${'"${2:-PATH}"'//:$_qdir:/:}"; [ "$'"${2:-PATH}"'" == "$1" ] && '"${2:-PATH}"'=' +} +function uaddpath() { + local _qdir="${1//\//\\/}" + eval "export ${2:-PATH}; "'[ "${'"${2:-PATH}"'#$1:}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'%:$1}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'//:$_qdir:/:}" == "$'"${2:-PATH}"'" -a "$'"${2:-PATH}"'" != "$1" ] && '"${2:-PATH}"'="${'"${2:-PATH}"':+$'"${2:-PATH}"':}$1"' +} +function uinspathm() { + local _qdir="${1//\//\\/}" + eval "export ${2:-PATH}; "'[ "${'"${2:-PATH}"'#$1:}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'%:$1}" == "$'"${2:-PATH}"'" -a "${'"${2:-PATH}"'//:$_qdir:/:}" == "$'"${2:-PATH}"'" -a "$'"${2:-PATH}"'" != "$1" ] && '"${2:-PATH}"'="$1${'"${2:-PATH}"':+:$'"${2:-PATH}"'}"' +} +function uinspath() { + udelpath "$@" + uinspathm "$@" +} + +function withpath() { + [ "${1#./}" != "$1" -o "${1#../}" != "$1" -o "${1#/}" != "$1" ] +} +function withext() { + local basename="$(basename -- "$1")" + [ "${basename%.*}" != "$basename" ] +} +function normpath() { + local -a parts + local part ap + array_split parts "$1" / + if [ "${1#/}" != "$1" ]; then + ap=/ + elif [ -n "$2" ]; then + ap="$2" + else + ap="$(pwd)" + fi + for part in "${parts[@]}"; do + if [ "$part" == "." ]; then + continue + elif [ "$part" == ".." ]; then + ap="${ap%/*}" + [ -n "$ap" ] || ap=/ + else + [ "$ap" != "/" ] && ap="$ap/" + ap="$ap$part" + fi + done + rawecho "$ap" +} +function abspath() { + local ap="$1" + if [ "${ap#/}" != "$ap" ]; then + __normpath "$ap" && return + else + local cwd + if [ -n "$2" ]; then + cwd="$(abspath "$2")" + else + cwd="$(pwd)" + fi + ap="$cwd/$ap" + __normpath "$ap" && return + fi + normpath "$ap" +} +function __normpath() { + if [ -d "$1" ]; then + if [ -x "$1" ]; then + (cd "$1"; pwd) + return 0 + fi + elif [ -f "$1" ]; then + local dn="$(dirname -- "$1")" bn="$(basename -- "$1")" + if [ -x "$dn" ]; then + (cd "$dn"; echo "$(pwd)/$bn") + return 0 + fi + fi + return 1 +} +function parentdirs() { + array_new "$1" + local __pd_d="$(abspath "$2")" + if [[ "$3" == r* ]]; then + while [ "$__pd_d" != "/" ]; do + array_ins "$1" "$__pd_d" + __pd_d="$(dirname "$__pd_d")" + done + else + while [ "$__pd_d" != "/" ]; do + array_add "$1" "$__pd_d" + __pd_d="$(dirname "$__pd_d")" + done + fi +} +function ppath() { + local path="$1" cwd="$2" + + path="$(abspath "$path")" # essayer de normaliser le chemin + [ -n "$cwd" ] || cwd="$(pwd)" + + [ "$path" = "$cwd" ] && path="." + [ "$cwd" != "/" -a "$cwd" != "$HOME" ] && path="${path/#$cwd\//}" + path="${path/#$HOME/~}" + + rawecho "$path" +} +function relpath() { + local p="$(abspath "$1" "$3")" cwd="$2" + if [ -z "$cwd" ]; then + cwd="$(pwd)" + else + cwd="$(abspath "$cwd" "$3")" + fi + if [ "$p" == "$cwd" ]; then + echo "" + elif [ "${p#$cwd/}" != "$p" ]; then + rawecho "${p#$cwd/}" + else + local rp + while [ -n "$cwd" -a "${p#$cwd/}" == "$p" ]; do + rp="${rp:+$rp/}.." + cwd="${cwd%/*}" + done + rp="$rp/${p#$cwd/}" + echo "${rp%//}" + fi +} +function relpathx() { + local p="$(relpath "$@")" + if [ -z "$p" ]; then + echo . + elif [ "${p#../}" != "$p" -o "${p#./}" != "$p" ]; then + echo "$p" + else + echo "./$p" + fi +} +function withinpath() { + local b="$1" p="$2" strict="${3:-N}" + b="$(abspath "$b")" + p="$(abspath "$p")" + if is_yes "$strict"; then + [ "${p#$b/}" != "$p" ] + else + [ "$p" == "$b" -o "${p#$b/}" != "$p" ] + fi +} +function safe_abspath() { + local p="$1" ba="$2" br="$3" + if [ -n "$ba" ]; then + ba="$(abspath "$ba")" + else + ba="$(pwd)" + fi + [ -n "$br" ] || br="$ba" + br="$(abspath "$br" "$ba")" + p="$(abspath "$p" "$ba")" + if [ "$p" == "$br" -o "${p#$br/}" != "$p" ]; then + echo "$p" + else + return 1 + fi +} +function safe_relpath() { + local p + if p="$(safe_abspath "$1" "$2" "$3")"; then + relpath "$p" "$2" "$(pwd)" + else + return 1 + fi +} +function splitwcs() { + local __sw_p="$1" + local __sw_dd="${2:-basedir}" __sw_df="${3:-filespec}" __sw_part __sw_d __sw_f + local -a __sw_parts + array_split __sw_parts "$__sw_p" "/" + for __sw_part in "${__sw_parts[@]}"; do + if [[ "$__sw_part" == *\** ]] || [[ "$__sw_part" == *\?* ]] || [ -n "$__sw_f" ]; then + __sw_f="${__sw_f:+$__sw_f/}$__sw_part" + else + __sw_d="${__sw_d:+$__sw_d/}$__sw_part" + fi + done + [ "${__sw_p#/}" != "$__sw_p" ] && __sw_d="/$__sw_d" + set_var "$__sw_dd" "$__sw_d" + set_var "$__sw_df" "$__sw_f" +} +function deref() { + local OENC="$UTF8" + + local max_deref=50 + local file="$1" + local basedir link + while [ -L "$file" ]; do + basedir="$(dirname "$file")" + link="$(readlink "$file")" + if first_char_is "$link" "/"; then + file="$link" + else + file="$basedir/$link" + fi + + max_deref=$(($max_deref - 1)) + [ $max_deref -eq 0 ] && die "Plus de 50 indirection. Le lien $file est-il récursif?" + done + abspath "$file" +} +function 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 + rawecho "$reldir$file" + else + rawecho "$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 [ -f "$2" ]; then + testdiff "$1" "$2" + else + return 0 + fi +} +function testnewer() { + test ! -e "$2" -o "$1" -nt "$2" +} +function ps_all() { + ps -axww +} +function progexists() { + test -n "$1" -a -x "$(which "$1" 2>/dev/null)" +} +function has_python() { + progexists python +} +function has_gawk() { + progexists gawk +} +function is_root() { + test `id -u` -eq 0 +} +function source_ifexists() { + if [ -f "$1" ]; then source "$1" || die; fi +} +function little_sleep { + LC_NUMERIC=C sleep 0.1 +} +function random_sleep { + sleep $(($RANDOM % ${1:-1800})) +} +function is_running() { + kill -0 "$1" >&/dev/null +} +function sedi() { + sed -i "$@" +} +function csort() { + LANG=C sort "$@" +} +function lsort() { sort "$@"; } +function cgrep() { + LANG=C grep "$@" +} +function lgrep() { grep "$@"; } +function csed() { + LANG=C sed "$@" +} +function lsed() { sed "$@"; } +function cawk() { + LANG=C awk "$@" +} +function lawk() { awk "$@"; } +function cdiff() { + LANG=C diff "$@" +} +function ldiff() { diff "$@"; } + + +function fix_mode() { + local file="$1" + [ -f "$file" ] || touch "$file" || return 1 + if [ ! -w "$file" ]; then + local mode="$(stat -c %a "$file")" + chmod ${mode:0:${#mode}-3}6${mode:${#mode}-2:2} "$file" + echo "$mode" + fi +} +function unfix_mode() { + [ -n "$2" ] && chmod "$2" "$1" +} +function get_mode() { + [ -f "$1" ] || touch "$1" || return 1 + stat -c %a "$1" +} +function rm_maybe() { + local parse_opts=1 arg rm + for arg in "$@"; do + if [ -n "$parse_opts" ]; then + if [ "$arg" == "--" ]; then + parse_opts= + elif [[ "$arg" == "-*" ]]; then + continue + elif [ -n "$arg" ]; then + rm=1 + break + fi + elif [ -n "$arg" ]; then + rm=1 + break + fi + done + [ -n "$rm" ] && /bin/rm "$@" +} +__CPDIR_RSYNC_SLOW=1 # synchro potentiellement plus lente, mais plus fidèle (option -c) +__CPDIR_RSYNC_ARGS=(-q) +function cpdir() { + + if progexists rsync; then + [ -d "$2" ] || mkdir -p "$2" || return 1 + if [ -d "$1" ]; then + rsync -a ${__CPDIR_RSYNC_SLOW:+-c} "${__CPDIR_RSYNC_ARGS[@]}" "$1/" "$2/" + else + rsync -a ${__CPDIR_RSYNC_SLOW:+-c} "${__CPDIR_RSYNC_ARGS[@]}" "$1" "$2/" + fi + else + __cpdir "$@" + fi +} +function __cpdir() { + local src="$1" dest="$2" method="${3:-cp_a}" + + if [ -d "$src" ]; then + [ -d "$dest" ] || mkdir -p "$dest" || return 1 + + local prevdir="$(pwd)" + + dest="$(abspath "$dest")" + cd "$src" + if [ -n "$(/bin/ls -a1)" ]; then + [ -n "$(/bin/ls -1)" ] && "$method" * "$dest" + local i + for i in .*; do + [ "$i" == "." -o "$i" == ".." ] && continue + "$method" "$i" "$dest" + done + fi + cd "$prevdir" + else + if [ -f "$dest" ]; then + "$method" "$src" "$dest" + elif [ -d "$dest" ]; then + "$method" "$src" "$dest" + else + mkdir -p "$dest" + "$method" "$src" "$dest" + fi + fi +} +__CPNOVCS_RSYNC_SLOW=1 # synchro potentiellement plus lente, mais plus fidèle (option -c) +__CPNOVCS_RSYNC_ARGS=(-q) +function cpnovcs() { + local src="$1" destdir="$2" + [ -d "$destdir" ] || mkdir -p "$destdir" || return 1 + if progexists rsync; then + local gitexclude=/.git/ + if [ "${src%/}" == "$src" ]; then + gitexclude="/$(basename -- "$src")$gitexclude" + fi + rsync -a ${__CPNOVCS_RSYNC_SLOW:+-c} --exclude CVS/ --exclude .svn/ --exclude "$gitexclude" "${__CPNOVCS_RSYNC_ARGS[@]}" "$src" "$destdir/" + elif [ "${src%/}" != "$src" ]; then + __cpdir "$src" "$destdir" + else + local srcname="$(basename -- "$src")" + mkdir -p "$destdir/$srcname" + __cpdir "$src" "$destdir/$srcname" + fi +} +function cpdirnovcs() { + if [ -d "$1" ]; then + cpnovcs "$1/" "$2" + else + cpnovcs "$1" "$2" + fi +} +function doinplace() { + if [ -n "$1" -a "$1" != "-" ]; then + local __dip_file="$1"; shift + autoclean "$__dip_file.tmp.$$" + "$@" <"$__dip_file" >"$__dip_file.tmp.$$" + local s=$? + [ "$s" == 0 ] && /bin/cat "$__dip_file.tmp.$$" >"$__dip_file" + /bin/rm -f "$__dip_file.tmp.$$" + return $s + else + shift + "$@" + fi +} +function doinplacef() { + if [ -n "$1" -a "$1" != "-" ]; then + local __dip_file="$1"; shift + autoclean "$__dip_file.tmp.$$" + "$@" <"$__dip_file" >"$__dip_file.tmp.$$" + local s=$? + /bin/cat "$__dip_file.tmp.$$" >"$__dip_file" + /bin/rm -f "$__dip_file.tmp.$$" + return $s + else + shift + "$@" + fi +} +function stripnl() { + tr -d '\r\n' +} +function _nl2lf() { + awk 'BEGIN {RS="\r|\r\n|\n"} {print}' +} +function nl2lf() { + doinplace "$1" _nl2lf +} +function _nl2crlf() { + awk 'BEGIN {RS="\r|\r\n|\n"} {print $0 "\r"}' +} +function nl2crlf() { + doinplace "$1" _nl2crlf +} +function _nl2cr() { + awk 'BEGIN {RS="\r|\r\n|\n"; ORS=""} {print $0 "\r"}' +} +function nl2cr() { + doinplace "$1" _nl2cr +} +function _latin1compat() { + LANG=fr_FR.UTF-8 sed $' +s/[\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/[œ]/oe/g +s/[Œ]/OE/g +s/[æ]/ae/g +s/[Æ]/AE/g +' +} +function _noaccents() { + LANG=fr_FR.UTF-8 sed ' +s/[à]/a/g +s/[éèêë]/e/g +s/[ïî]/i/g +s/[ôö]/o/g +s/[üû]/u/g +s/[ç]/c/g +s/[À]/A/g +s/[ÉÈÊË]/E/g +s/[ÏÎ]/I/g +s/[ÔÖ]/O/g +s/[ÜÛ]/U/g +s/[Ç]/C/g +' +} +function list_all() { + local curdir="$(pwd)" + local b="${1:-.}"; shift + + cd "$b" 2>/dev/null || return + eval "$(__la_cmd "$@")" | while read f; do + [ "$f" == "." -o "$f" == ".." ] && continue + rawecho "$f" + done + cd "$curdir" +} +function __la_cmd() { + [ $# -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" ] && rawecho "$f" + done + cd "$curdir" +} +function list_dirs() { + local f + local curdir="$(pwd)" + local b="${1:-.}"; shift + + cd "$b" 2>/dev/null || return + eval "$(__la_cmd "$@")" | while read f; do + [ "$f" == "." -o "$f" == ".." ] && continue + [ -d "$f" ] && rawecho "$f" + done + cd "$curdir" +} +function __array_ls() { + local __al_l="list_${1:-all}"; shift + local __al_an="$1"; shift + local __al_d="${1:-.}"; shift + local -a __al_fs + array_from_lines __al_fs "$("$__al_l" "$__al_d" "$@")" + local __al_f + array_new "$__al_an" + for __al_f in "${__al_fs[@]}"; do + array_add "$__al_an" "$__al_d/$__al_f" + done +} +function array_lsall() { + __array_ls all "$@" +} +function array_lsdirs() { + __array_ls dirs "$@" +} +function array_lsfiles() { + __array_ls files "$@" +} +function filter_empty() { + sed '/^$/d' +} +function filter_vcspath() { + sed ' +/^.git$/d +/^.git\//d +/\/.git$/d +/\/.git\//d +/^.svn$/d +/^.svn\//d +/\/.svn$/d +/\/.svn\//d +' +} +function merge_contlines() { + awk 'substr($0, length($0)) == "\\" { + while (getline nextline) { + $0 = substr($0, 1, length($0) - 1) nextline + if (substr($0, length($0)) != "\\") break + } + print + next +} +{print}' +} +function filter_comment() { + local -a merge + [ "$1" == -m ] && merge=(merge_contlines) || merge=(cat) + awk ' + /^[ \t]*#/ { next } + /^[ \t]*$/ { next } + { print }' | "${merge[@]}" +} +function filter_conf() { + local -a merge + [ "$1" == -m ] && merge=(merge_contlines) || merge=(cat) + grep -v '^#' | grep -v '^$' | "${merge[@]}" +} +function is_archive() { + local name="${1%.zip}" + name="${name%.tgz}" + name="${name%.tbz2}" + name="${name%.tar.gz}" + name="${name%.tar.bz2}" + name="${name%.tar}" + name="${name%.jar}" + name="${name%.war}" + name="${name%.ear}" + [ "$name" != "$1" ] +} +function extract_archive() { + local arch="$1" destdir="${2:-.}" + shift; shift + if endswith "$arch" .zip; then + unzip -q -d "$destdir" "$arch" "$@" || return + elif endswith "$arch" .tgz || endswith "$arch" .tar.gz; then + tar xzf "$arch" -C "$destdir" "$@" || return + elif endswith "$arch" .tbz2 || endswith "$arch" .tar.bz2; then + tar xjf "$arch" -C "$destdir" "$@" || return + elif endswith "$arch" .tar; then + tar xf "$arch" -C "$destdir" "$@" || return + elif endswith "$arch" .jar || endswith "$arch" .war || endswith "$arch" .ear; then + ( + arch="$(abspath "$arch")" + cd "$destdir" + jar xf "$arch" "$@" + ) || return + else + return 1 + fi +} +function get_archive_basename() { + local basename="$(basename -- "$1")" + basename="${basename%.zip}" + basename="${basename%.tgz}" + basename="${basename%.tbz2}" + basename="${basename%.gz}" + basename="${basename%.bz2}" + basename="${basename%.tar}" + basename="${basename%.jar}" + basename="${basename%.war}" + basename="${basename%.ear}" + echo "$basename" +} +function get_archive_appname() { + local appname="$(basename -- "$1")" + appname="${appname%.zip}" + appname="${appname%.tgz}" + appname="${appname%.tbz2}" + appname="${appname%.gz}" + appname="${appname%.bz2}" + appname="${appname%.tar}" + appname="${appname%.jar}" + appname="${appname%.war}" + appname="${appname%.ear}" + echo "$appname" | awk '{ + if (match($0, /[-_.]([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/)) { + print substr($0, 1, RSTART - 1) + } else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/)) { + print substr($0, 1, RSTART - 1) + } else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) { + print substr($0, 1, RSTART - 1) + } else { + print $0 + } +}' +} +function get_archive_versionsuffix() { + local basename="$(get_archive_basename "$1")" + echo "$basename" | awk '{ + if (match($0, /([-_.][0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) { + print vs["1"] + } else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) { + print vs["1"] + } else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) { + print vs["1"] + } +}' +} +function get_archive_version() { + local basename="$(get_archive_basename "$1")" + echo "$basename" | awk '{ + if (match($0, /[-_.]([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) { + print vs["1"] + } else if (match($0, /([0-9]+([-_.][0-9]+)*([a-zA-Z][0-9]*|[-_.][0-9]+[a-zA-Z][0-9]*)?)$/, vs)) { + print vs["1"] + } else if (match($0, /([0-9]+[a-z][a-z][a-z0-9]?)$/, vs)) { + print vs["1"] + } +}' +} +function __dump_usernames() { + = 500 && $6 ~ /^\/home\// { print $1 }' +} +function dump_usernames() { + array_from_lines "${1:-usernames}" "$(__dump_usernames)" +} +function __resolv_ips() { + LANG=C host "$1" 2>/dev/null | awk '/address / { gsub(/^.*address /, ""); print }' +} +function resolv_ips() { + array_from_lines "${1:-ips}" "$(__resolv_ips "$2")" +} +function __resolv_hosts() { + LANG=C host "$1" 2>/dev/null | awk '/domain name pointer / { gsub(/^.*domain name pointer /, ""); gsub(/\.$/, ""); print }' +} +function resolv_hosts() { + array_from_lines "${1:-hosts}" "$(__resolv_hosts "$2")" +} +function runscript_as() { + local OENC="$UTF8" + local user="${1:-root}"; shift + local exec_maybe= + if [ "$1" = "exec" ]; then + exec_maybe=exec + shift + fi + + local cmd + cmd="\ +__estack=$(quoted_arg "$__estack") +__tlevel=$(quoted_args "$__tlevel") +export __estack __tlevel +exec ${BASH:-/bin/sh} $(quoted_args "$@")" + + if is_yes "$UTOOLS_USES_SU" || ! progexists sudo; then + eecho "Entrez le mot de passe de root" + $exec_maybe su "$user" -c "$cmd" + else + if [ "$user" == "root" ]; then + $exec_maybe sudo -p "Entrez le mot de passe de %u: " "${BASH:-/bin/sh}" -c "$cmd" + else + $exec_maybe sudo -p "Entrez le mot de passe de %u: " su "$user" -c "$cmd" + fi + fi +} +function runscript_as_root() { + if is_root; then + local exec_maybe= + if [ "$1" = "exec" ]; then + exec_maybe=exec + shift + fi + $exec_maybe "${BASH:-/bin/sh}" "$@" + else + runscript_as root "$@" + fi +} +function run_as() { + local user="${1:-root}"; shift + local exec_maybe=exec + if [ "$1" = "--noexec" ]; then + exec_maybe= + shift + fi + + runscript_as "$user" $exec_maybe "$0" "$@" +} +function run_as_root() { + is_root || run_as root "$@" +} +function check_user() { + local user + for user in "$@"; do + [ "$USER" == "$user" ] && return 0 + done + return 1 +} +function ensure_user() { + local -a users + while [ $# -gt 0 -a "$1" != "--" ]; do + array_add users "$1" + shift + done + [ "$1" == "--" ] && shift + + if ! check_user "${users[@]}"; then + if [ ${#users[*]} -gt 1 ]; then + ewarn "Cette commande doit être lancée avec l'un des users ${users[*]}" + else + ewarn "Cette commande doit être lancée avec le user ${users[0]}" + fi + if ask_yesno "Voulez-vous tenter de relancer la commande avec le bon user?" O; then + estep "Lancement du script avec le user ${users[0]}" + run_as "${users[0]}" "$@" + return 1 + elif is_root; then + return 11 + else + return 10 + fi + fi + return 0 +} +function check_hostname() { + local userhost user host path + for userhost in "$@"; do + splitfsep "$userhost" : userhost path + splituserhost "$userhost" user host + 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 + + enote "Vous pouvez tenter de relancer le script sur ${userhosts[0]}, mais cela requière que ce script ET les données dont il a besoin soient installés dans la même version et dans le même répertoire sur l'hôte distant" + if ask_yesno "Voulez-vous tenter de relancer le script sur l'hôte distant?" N; then + splitfsep "${userhosts[0]}" : userhost path + splituserhost "$userhost" user host + [ -n "$user" ] || user=root + + estep "Lancement de la commande sur l'hôte distant $user@$host" + local cmd + [ -n "$path" ] && cmd="$(quoted_args cd "$path"); " + cmd="$cmd$(quoted_args "$script" "$@")" + ssh -qt "${UTOOLS_ENSURE_HOSTNAME_SSH_OPTS[@]}" "$user@$host" "$cmd" + [ $? -eq 255 ] && return 12 + return 1 + else + return 11 + fi + fi + local userhost user host + for userhost in "${userhosts[@]}"; do + [[ "$userhost" == *@* ]] || continue + if check_hostname "$userhost"; then + splitfsep "$userhost" : userhost path + splituserhost "$userhost" user host + [ -n "$path" ] && cd "$path" + ensure_user "$user" -- "$@" + return $? + fi + done + return 0 +} + +__AWKDEF_FUNCTIONS=' +function 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 quote_html(s) { + gsub(/&/, "\\&", s) + gsub(/"/, "\\"", s) + gsub(/>/, "\\>", s) + gsub(/", s) + gsub(/"/, "\"", s) + gsub(/&/, "\\&", s) + return s +} +function quote_value(s) {'" + gsub(/'/, \"'\\\\''\", s) + return \"'\" s \"'\" +"'} +function quoted_values( i, line) { + line = "" + for (i = 1; i <= NF; i++) { + if (i > 1) line = line " " + line = line quote_value($i) + } + return line +} +function quote_regexp(s) { + gsub(/[[\\.^$*+?()|{]/, "\\\\&", s) + return s +} +function quote_subrepl(s) { + gsub(/\\/, "\\\\", s) + gsub(/&/, "\\\\&", s) + return s +} +function quote_grep(s) { + gsub(/[[\\.^$*]/, "\\\\&", s) + return s +} +function quote_egrep(s) { + gsub(/[[\\.^$*+?()|{]/, "\\\\&", s) + return s +} +function quote_sql(s) {'" + gsub(/'/, \"''\", s) + return \"'\" s \"'\" +"'} +function unquote_mysqlcsv(s) { + gsub(/\\n/, "\n", s) + gsub(/\\t/, "\t", s) + gsub(/\\0/, "\0", s) + gsub(/\\\\/, "\\", s) + return s +} + +function __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)) + } + 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 array_new(dest) { + dest[0] = 0 # forcer awk à considérer dest comme un tableau + delete dest +} +function array_newsize(dest, size, i) { + dest[0] = 0 # forcer awk à considérer dest comme un tableau + delete dest + size = int(size) + for (i = 1; i <= size; i++) { + dest[i] = "" + } +} +function array_len(values, count, i) { + count = 0 + for (i in values) { + count++ + } + return count +} +function mkindices(values, indices, i, j) { + array_new(indices) + j = 1 + for (i in values) { + indices[j++] = int(i) + } + return asort(indices) +} +function array_copy(dest, src, count, indices, i) { + array_new(dest) + count = mkindices(src, indices) + for (i = 1; i <= count; i++) { + dest[indices[i]] = src[indices[i]] + } +} +function array_getlastindex(src, count, indices) { + count = mkindices(src, indices) + if (count == 0) return 0 + return indices[count] +} +function array_add(dest, value, lastindex) { + lastindex = array_getlastindex(dest) + dest[lastindex + 1] = value +} +function array_deli(dest, i, l) { + i = int(i) + if (i == 0) return + l = array_len(dest) + while (i < l) { + dest[i] = dest[i + 1] + i++ + } + delete dest[l] +} +function array_del(dest, value, ignoreCase, i) { + do { + i = key_index(value, dest, ignoreCase) + if (i != 0) array_deli(dest, i) + } while (i != 0) +} +function array_extend(dest, src, count, lastindex, indices, i) { + lastindex = array_getlastindex(dest) + count = mkindices(src, indices) + for (i = 1; i <= count; i++) { + dest[lastindex + i] = src[indices[i]] + } +} +function array_fill(dest, i) { + array_new(dest) + for (i = 1; i <= NF; i++) { + dest[i] = $i + } +} +function array_getline(src, count, indices, i, j) { + $0 = "" + count = mkindices(src, indices) + for (i = 1; i <= count; i++) { + j = indices[i] + $j = src[j] + } +} +function array_appendline(src, count, indices, i, nf, j) { + count = mkindices(src, indices) + nf = NF + for (i = 1; i <= count; i++) { + j = nf + indices[i] + $j = src[indices[i]] + } +} +function in_array(value, values, ignoreCase, i) { + if (ignoreCase) { + value = tolower(value) + for (i in values) { + if (tolower(values[i]) == value) return 1 + } + } else { + for (i in values) { + if (values[i] == value) return 1 + } + } + return 0 +} +function key_index(value, values, ignoreCase, i) { + if (ignoreCase) { + value = tolower(value) + for (i in values) { + if (tolower(values[i]) == value) return int(i) + } + } else { + for (i in values) { + if (values[i] == value) return int(i) + } + } + return 0 +} +function array2s(values, prefix, sep, suffix, noindices, first, i, s) { + if (!prefix) prefix = "[" + if (!sep) sep = ", " + if (!suffix) suffix = "]" + s = prefix + first = 1 + for (i in values) { + if (first) first = 0 + else s = s sep + if (!noindices) s = s "[" i "]=" + s = s values[i] + } + s = s suffix + return s +} +function array2so(values, prefix, sep, suffix, noindices, count, indices, i, s) { + if (!prefix) prefix = "[" + if (!sep) sep = ", " + if (!suffix) suffix = "]" + s = prefix + count = mkindices(values, indices) + for (i = 1; i <= count; i++) { + if (i > 1) s = s sep + if (!noindices) s = s "[" indices[i] "]=" + s = s values[indices[i]] + } + s = s suffix + return s +} +function array_join(values, sep, prefix, suffix, count, indices, i, s) { + s = prefix + count = mkindices(values, indices) + for (i = 1; i <= count; i++) { + if (i > 1) s = s sep + s = s values[indices[i]] + } + s = s suffix + return s +} +function printto(s, output) { + if (output == "") { + print s + } else if (output ~ /^>>/) { + sub(/^>>/, "", output) + print s >>output + } else if (output ~ /^>/) { + sub(/^>/, "", output) + print s >output + } else { + print s >output + } +} +function find_line(input, field, value, orig, line) { + orig = $0 + line = "" + while ((getline 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() { + + if [ "${1:0:3}" == "-f" ]; then + shift + echo "$__AWKDEF_FUNCTIONS" + fi + if [ $# -gt 0 ]; then + local __ad_arg __ad_vpos __ad_name __ad_value + echo "BEGIN {" + while [ -n "${1:0:1}" ]; do + __ad_arg="${1:0:256}" + local __ad_array= + if [ "${__ad_arg%\[@\]}" != "$__ad_arg" ]; then + __ad_array=1 + __ad_name="${__ad_arg%\[@\]}" + [ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break + __ad_value="$__ad_name" + elif [[ "$__ad_arg" == *\[@\]=* ]]; then + __ad_array=1 + __ad_name="${__ad_arg%%\[@\]=*}" + [ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break + __ad_vpos=$((${#__ad_name} + 4)) + __ad_value="${1:$__ad_vpos}" + [ ${#__ad_value} -ne 0 ] || __ad_value="$__ad_name" + elif [[ "$__ad_arg" == *=* ]]; then + local __ad_int= __ad_str= + __ad_name="${__ad_arg%%=*}" + __ad_vpos=$((${#__ad_name} + 1)) + if [ "${__ad_name%:int}" != "$__ad_name" ]; then + __ad_int=1 + __ad_name="${__ad_name%:int}" + elif [ "${__ad_name%:str}" != "$__ad_name" ]; then + __ad_str=1 + __ad_name="${__ad_name%:str}" + fi + [ -z "${__ad_name//[a-zA-Z0-9_]/}" ] || break + __ad_value="${1:$__ad_vpos}" + if [ -n "$__ad_int" ]; then + echo "$__ad_name = int($(quoted_awk "$__ad_value") + 0)" + elif [ -n "$__ad_str" ]; then + echo "$__ad_name = $(quoted_awk "$__ad_value")" + elif [ ${#__ad_value} -lt 256 ] && isnum "$__ad_value"; then + echo "$__ad_name = $__ad_value" + else + echo "$__ad_name = $(quoted_awk "$__ad_value")" + fi + else + break + fi + if [ -n "$__ad_array" ]; then + if [ "${__ad_value:0:2}" == $'<\n' ]; then + local -a __ad_values + array_from_lines __ad_values "${__ad_value:2}" + __ad_value=__ad_values + fi + __ad_value="${__ad_value}[@]" + local __ad_i=1 + echo "$__ad_name[0] = 0; delete $__ad_name" + for __ad_arg in "${!__ad_value}"; do + echo "$__ad_name[$__ad_i]=$(quoted_awk "$__ad_arg")" + __ad_i=$(($__ad_i + 1)) + done + eval "echo \"\${__ad_name}_count = \${#$__ad_value}\"" + fi + shift + done + echo "}" + for __ad_arg in "$@"; do + rawecho "$__ad_arg" + done + fi +} +function lawkrun() { + local -a __ar_defs __ar_args + while [ $# -gt 0 -a "$1" != "--" ]; do + __ar_defs=("${__ar_defs[@]}" "$1") + shift + done + shift + while [ $# -gt 0 ]; do + __ar_args=("${__ar_args[@]}" "$1") + shift + done + local __ar_script="$(awkdef "${__ar_defs[@]}")" + [ -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 -XF "$@" + 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 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 +} + +TAB=$'\t' +LATIN1=iso-8859-1 +LATIN9=iso-8859-15 +UTF8=utf-8 +OENC="$UTF8" + +if ! progexists iconv; then + function iconv() { cat; } +fi + +function __lang_encoding() { + local lang="$(<<<"$LANG" awk '{ print tolower($0) }')" + case "$lang" in + *@euro) echo "iso-8859-15";; + *.utf-8|*.utf8) echo "utf-8";; + *) echo "iso-8859-1";; + esac +} +function __norm_encoding() { + awk '{ + enc = tolower($0) + gsub(/^latin$/, "latin1", enc) + gsub(/^latin1$/, "iso-8859-1", enc) + gsub(/^latin9$/, "iso-8859-15", enc) + gsub(/[-_]/, "", enc) + if (enc == "iso8859" || enc == "iso88591" || enc == "8859" || enc == "88591") print "iso-8859-1" + else if (enc == "iso885915" || enc == "885915") print "iso-8859-15" + else if (enc == "utf" || enc == "utf8") print "utf-8" + else print $0 + }' <<<"$1" +} +function __init_encoding() { + local DEFAULT_ENCODING="$(__lang_encoding)" + [ -n "$DEFAULT_ENCODING" ] || DEFAULT_ENCODING=utf-8 + [ -n "$UTOOLS_OUTPUT_ENCODING" ] || UTOOLS_OUTPUT_ENCODING="$DEFAULT_ENCODING" + UTOOLS_OUTPUT_ENCODING="$(__norm_encoding "$UTOOLS_OUTPUT_ENCODING")" + [ -n "$UTOOLS_INPUT_ENCODING" ] || UTOOLS_INPUT_ENCODING="$UTOOLS_OUTPUT_ENCODING" + UTOOLS_INPUT_ENCODING="$(__norm_encoding "$UTOOLS_INPUT_ENCODING")" + [ -n "$UTOOLS_EDITOR_ENCODING" ] || UTOOLS_EDITOR_ENCODING="$UTOOLS_INPUT_ENCODING" + UTOOLS_EDITOR_ENCODING="$(__norm_encoding "$UTOOLS_EDITOR_ENCODING")" + + IENC="$UTOOLS_INPUT_ENCODING" + OENC="$UTOOLS_OUTPUT_ENCODING" +} + +if [ -n "$UTOOLS_LANG" -a -z "$LANG" ]; then + export UTOOLS_LANG + export LANG="$UTOOLS_LANG" +fi +__init_encoding + +function tooenc() { + local src="$1" from="${2:-$OENC}" to="${3:-$UTOOLS_OUTPUT_ENCODING}" + if [ "$from" == "$to" ]; then + rawecho "$src" + else + iconv -f "$from" -t "$to" <<<"$src" + fi +} +function uecho() { + tooenc "$*" +} +function tooenc_() { + local src="$1" from="${2:-$OENC}" to="${3:-$UTOOLS_OUTPUT_ENCODING}" + if [ "$from" == "$to" ]; then + rawecho_ "$src" + else + rawecho_ "$src" | iconv -f "$from" -t "$to" + fi +} +function uecho_() { + tooenc_ "$*" +} +function toienc() { + local __tie_var="$1" __tie_to="${2:-$IENC}" __tie_from="${3:-$UTOOLS_INPUT_ENCODING}" + if [ "$__tie_from" != "$__tie_to" ]; then + set_var "$__tie_var" "$(iconv -f "$__tie_from" -t "$__tie_to" <<<"${!__tie_var}")" + fi +} +function uread() { + [ $# -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 + rawecho "$1" + fi +} +function __eerror() { tooenc "$(__edate)${__tlevel}E $(__indent "$1")"; } +function __ewarn() { tooenc "$(__edate)${__tlevel}W $(__indent "$1")"; } +function __enote() { tooenc "$(__edate)${__tlevel}N $(__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}! $(__indent "$1")"; } +function __eattention() { tooenc "$(__edate)${__tlevel}* $(__indent "$1")"; } +function __einfo() { tooenc "$(__edate)${__tlevel}I $(__indent "$1")"; } +function __eecho() { tooenc "$(__edate)${__tlevel}$(__indent "$1")"; } +function __eecho_() { tooenc_ "$(__edate)${__tlevel}$(__indent "$1")"; } +function __edebug() { tooenc "$(__edate)${__tlevel}D $(__indent "$1")"; } +function __estep() { tooenc "$(__edate)${__tlevel}. $(__indent "$1")"; } +function __estepe() { __estep "$@"; } +function __estepw() { __estep "$@"; } +function __estepn() { __estep "$@"; } +function __estepi() { __estep "$@"; } +function __estep_() { tooenc_ "$(__edate)${__tlevel}. $(__indent "$1")"; } +function __estepe_() { __estep_ "$@"; } +function __estepw_() { __estep_ "$@"; } +function __estepn_() { __estep_ "$@"; } +function __estepi_() { __estep_ "$@"; } +function __etitle() { tooenc "$(__edate)${__tlevel}T $(__indent "$1")"; } +function __ebegin() { tooenc_ "$(__edate)${__tlevel}. $(__indent "$1"): "; } +function __edoto() { echo_ "."; } +function __edotw() { echo_ "w"; } +function __edotx() { echo_ "x"; } +function __edotp() { echo_ "+"; } +function __edotd() { tooenc "($1)"; } +function __eendo() { echo "[ok]"; } +function __eendx() { echo "[error]"; } +PRETTYOPTS=() +function set_verbosity() { :;} +function set_interaction() { :;} +function show_error() { + return 0 +} +function show_warn() { + return 0 +} +function show_info() { + return 0 +} +function show_verbose() { + return 0 +} +function show_debug() { + [ -n "$DEBUG" ] +} +function check_verbosity() { + return 0 +} +function get_verbosity_option() { :;} +function check_interaction() { + return 0 +} +function is_interaction() { + return 1 +} +function get_interaction_option() { :;} +__epending= +function eflush() { + if [ -n "$__epending" ]; then rawecho "$__epending" 1>&2; __epending=; fi +} +function eclearp() { + __epending= +} +function eerror() { + show_error || return; eflush; __eerror "$*" 1>&2 +} +function ewarn() { + show_warn || return; eflush; __ewarn "$*" 1>&2 +} +function enote() { + show_info || return; eflush; __enote "$*" 1>&2 +} +function ebanner() { + show_error || return; eflush; __ebanner "$*" 1>&2; sleep 5 +} +function eimportant() { + show_error || return; eflush; __eimportant "$*" 1>&2 +} +function eattention() { + show_warn || return; eflush; __eattention "$*" 1>&2 +} +function einfo() { + show_info || return; eflush; __einfo "$*" 1>&2 +} +function eecho() { + show_info || return; eflush; __eecho "$*" 1>&2 +} +function eecho_() { + show_info || return; eflush; __eecho_ "$*" 1>&2 +} +function edebug() { + show_debug || return; eflush; __edebug "$*" 1>&2 +} +function trace() { + local r cmd="$(quoted_args "$@")" + show_info && { eflush; __eecho "\$ $cmd" 1>&2; } + "$@"; r=$? + if [ $r -ne 0 ]; then + if show_info; then + eflush; __eecho "^ [EC #$r]" 1>&2 + elif show_error; then + eflush; __eecho "^ $cmd [EC #$r]" 1>&2; + fi + fi + return $r +} +function trace_error() { + local r + "$@"; r=$? + if [ $r -ne 0 ]; then + local cmd="$(quoted_args "$@")" + show_error && { eflush; __eecho "^ $cmd [EC #$r]" 1>&2; } + fi + return $r +} + +function etitle() { + local __t_deferred= + __t_etitle "$@" +} +function etitled() { + local __t_deferred=1 + __t_etitle "$@" +} +function __t_etitle() { + local __t_eend=default + local __t_clearp= + while [ -n "$1" ]; do + if [ "$1" == "--" ]; then + shift + break + elif [ "$1" == "-s" ]; then + __t_eend= + shift + elif [ "$1" == "--eend" ]; then + __t_eend=1 + shift + elif [ "$1" == "-p" ]; then + __t_clearp=1 + shift + else + break + fi + done + local __t_title="$1"; shift + local __t_s=0 + [ -n "$__estack" ] && __tlevel="${__tlevel} " + __estack="$__estack:t" + if show_info; then + if [ -n "$__t_deferred" ]; then + __epending="${__epending:+$__epending +}$(__etitle "$__t_title")" + else + eflush + __etitle "$__t_title" 1>&2 + fi + fi + if [ $# -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 + tooenc_ "$message" 1>&2 + else + tooenc_ "Voulez-vous continuer?" "$UTF8" 1>&2 + fi + tooenc_ " $prompt " "$UTF8" 1>&2 + uread r + is_yes "${r:-$default}" + else + is_yes "$default" + fi +} +function read_value() { + local -a __rv_opts __rv_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 + set_var "$__rv_v" "$__rv_d" + return 0 + fi + + eflush + local __rv_r + while true; do + if [ -n "$__rv_msg" ]; then + tooenc_ "$__rv_msg" 1>&2 + else + tooenc_ "Entrez la valeur" "$UTF8" 1>&2 + fi + if [ -n "$__rv_readline" ]; then + tooenc_ ": " "$UTF8" 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 + tooenc_ ": " "$UTF8" 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 + set_var "$__rv_v" "$__rv_r" + return 0 + fi + done +} +function simple_menu() { + local __sm_title= __sm_yourchoice= __sm_default= + local -a __sm_args + parse_opts -t: __sm_title= -m: __sm_yourchoice= -d: __sm_default= @ __sm_args -- "$@" && + set -- "${__sm_args[@]}" || ewarn "$__sm_args" + + local __sm_option_var="${1:-option}" __sm_options_var="${2:-options}" + local __sm_option __sm_options + __sm_options="$__sm_options_var[*]" + if [ -z "${!__sm_options}" ]; then + OENC="$UTF8" eerror "Le tableau $__sm_options_var doit être non vide" + return 1 + fi + [ -z "$__sm_default" ] && __sm_default="${!__sm_option_var}" + + eflush + array_copy __sm_options "$__sm_options_var" + local __sm_c=0 __sm_i __sm_choice + while true; do + if [ "$__sm_c" == "0" ]; then + [ -n "$__sm_title" ] && tooenc "=== $__sm_title ===" 1>&2 + __sm_i=1 + for __sm_option in "${__sm_options[@]}"; do + if [ "$__sm_option" == "$__sm_default" ]; then + tooenc "$__sm_i*- $__sm_option" 1>&2 + else + tooenc "$__sm_i - $__sm_option" 1>&2 + fi + let __sm_i=$__sm_i+1 + done + fi + + if [ -n "$__sm_yourchoice" ]; then + tooenc_ "$__sm_yourchoice" 1>&2 + else + tooenc_ "Entrez le numéro de l'option choisie" "$UTF8" 1>&2 + fi + tooenc_ ": " "$UTF8" 1>&2 + uread __sm_choice + + if [ -z "$__sm_choice" -a -n "$__sm_default" ]; then + __sm_option="$__sm_default" + break + fi + if [ -n "$__sm_choice" -a -z "${__sm_choice//[0-9]/}" ]; then + if [ "$__sm_choice" -gt 0 -a "$__sm_choice" -le "${#__sm_options[*]}" ]; then + __sm_option="${__sm_options[$(($__sm_choice - 1))]}" + break + else + OENC="$UTF8" eerror "Numéro d'option incorrect" + fi + else + OENC="$UTF8" eerror "Vous devez saisir le numéro de l'option choisie" + fi + + let __sm_c=$__sm_c+1 + if [ "$__sm_c" -eq 5 ]; then + tooenc "" "$UTF8" 1>&2 + __sm_c=0 + fi + done + set_var "$__sm_option_var" "$__sm_option" +} + +function 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 + set_var "$1" "$3" + [ -f "$3" -a "$4" == keep ] || >"$3" + else + local __acst_t="$(mktempf "$2")" + autoclean "$__acst_t" + set_var "$1" "$__acst_t" + fi +} +function ac_set_tmpdir() { + local __acst_d + if show_debug; then + if [ -n "$4" ]; then + is_yes "${!4}" && __acst_d=1 + else + __acst_d=1 + fi + fi + if [ -n "$__acst_d" -a -n "$3" ]; then + set_var "$1" "$3" + mkdir -p "$3" + else + local __acst_t="$(mktempd "$2")" + autoclean "$__acst_t" + set_var "$1" "$__acst_t" + fi +} +function debug_tee() { + if show_debug; then + tee "$@" + else + cat + fi +} + + +function get_defaults_files() { + local __gd_dest="${1:-defaults}"; shift + local -a __gd_fs + local __gd_f __gd_found + for __gd_f in "$@"; do + __gd_found= + if [ -r "/etc/default/$__gd_f" ]; then + __gd_fs=("${__gd_fs[@]}" "/etc/default/$__gd_f") + __gd_found=1 + fi + if [ -r "$HOME/etc/default.${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[../sysinfos +## Gestion des informations sur l'hôte local +##@require base +uprovide sysinfos +urequire base + + +SYSNAMES=(linux linux64 linux32 linuxppc64 linuxppc32 linuxarm macosx) +linux_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo) +linux32_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo) +linux64_SYSDISTS=(debianlike debian ubuntu redhatlike rhel fedora centos suse gentoo) +linuxppc32_SYSDISTS=(debianlike debian ubuntu redhatlike fedora) +linuxppc64_SYSDISTS=(debianlike debian ubuntu redhatlike fedora) +linuxarm_SYSDISTS=(debianlike debian ubuntu) +macosx_SYSDISTS=(lion snowleopard leopard tiger panther) +SYSDIST_ALIASES=( + 10.7=lion 10.6=snowleopard 10.5=leopard 10.4=tiger 10.3=panther +) +debianlike_SYSVERS=() +debian_SYSVERS=(stretch jessie wheezy squeeze lenny etch) +ubuntu_SYSVERS=(oneiric natty maverick lucid karmic jaunty intrepid hardy) +redhatlike_SYSVERS=() +rhel_SYSVERS=(rhel7 rhel6 rhel5 rhel4 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=( + 9=stretch 8=jessie 7=wheezy 6=squeeze 5=lenny 4=etch + 11.10=oneiric 11.04=natty 10.10=maverick 10.04=lucid 9.10=karmic 9.04=jaunty 8.10=intrepid 8.04=hardy +) + +function __setup_ALL_SYSvars() { + local s ds d fs f + ALL_SYSDISTS=() + for s in "${SYSNAMES[@]}"; do + array_copy ds "${s}_SYSDISTS" + for d in "${ds[@]}"; do + array_set ALL_SYSDISTS "$d" + done + done + ALL_SYSVERS=() + for d in "${ALL_SYSDISTS[@]}"; do + array_copy fs "${d}_SYSVERS" + for f in "${fs[@]}"; do + array_contains ALL_SYSVERS "$f" && array_del ALL_SYSVERS "$f" + array_add ALL_SYSVERS "$f" + done + done +} +__setup_ALL_SYSvars +unset -f __setup_ALL_SYSvars + +MYSYSNAME=() +MYBITS= +MYSYSDIST=() +MYSYSVER=() +if [ "$UNAME_SYSTEM" == "Linux" ]; then + case "$UNAME_MACHINE" in + x86_64) + MYSYSNAME=(linux64 linux) + MYBITS=64 + ;; + i386|i586|i686) + MYSYSNAME=(linux32 linux) + MYBITS=32 + ;; + ppc) + MYSYSNAME=(linuxppc32 linuxppc linux) + MYBITS=32 + ;; + ppc64) + MYSYSNAME=(linuxppc64 linuxppc linux) + MYBITS=64 + ;; + arm*) + MYSYSNAME=(linuxarm linux) + ;; + *) + MYSYSNAME=(linux) + ;; + esac + + if [ -f /etc/debian_version ]; then + case "$(//g +s/<\/string>.*$//g' + break + fi + done + } + MYSYSNAME=(macosx darwin) + case "$(get_macosx_version)" in + 10.7*) MYSYSDIST=(lion);; + 10.6*) MYSYSDIST=(snowleopard);; + 10.5*) MYSYSDIST=(leopard);; + 10.4*) MYSYSDIST=(tiger);; + 10.3*) MYSYSDIST=(panther);; + esac +fi +if [ -n "$UTOOLS_CHROOT" ]; then + [ -n "$UTOOLS_SYSNAME" ] && eval "MYSYSNAME=($UTOOLS_SYSNAME)" + [ -n "$UTOOLS_BITS" ] && eval "MYBITS=$UTOOLS_BITS" + [ -n "$UTOOLS_SYSDIST" ] && eval "MYSYSDIST=($UTOOLS_SYSDIST)" + [ -n "$UTOOLS_SYSVER" ] && eval "MYSYSVER=($UTOOLS_SYSVER)" +fi + +function __get_sysdist_alias() { + if ! array_contains ALL_SYSDISTS "$1"; then + local nd n d + for nd in "${SYSDIST_ALIASES[@]}"; do + splitvar "$nd" n d + if [ "$n" == "$1" ]; then + echo "$d" + return + fi + done + fi + echo "$1" +} + +function __get_sysver_alias() { + if ! array_contains ALL_SYSVERS "$1"; then + local nv n v + for nv in "${SYSVER_ALIASES[@]}"; do + splitvar "$nv" n v + if [ "$n" == "$1" ]; then + echo "$v" + return + fi + done + fi + echo "$1" +} + +function __fix_sysinfos_upward() { + local sysname_ sysdists_ sysdist_ sysvers_ sysver_ + if [ -z "${!sysnamevar_}" ]; then + if [ -z "${!sysdistvar_}" ]; then + [ -z "${!sysvervar_}" ] && return + for sysname_ in "${SYSNAMES[@]}"; do + array_copy sysdists_ "${sysname_}_SYSDISTS" + for sysdist_ in "${sysdists_[@]}"; do + array_copy sysvers_ "${sysdist_}_SYSVERS" + for sysver_ in "${sysvers_[@]}"; do + if [ "$sysver_" == "${!sysvervar_}" ]; then + set_var "$sysdistvar_" "$sysdist_" + set_var "$sysnamevar_" "$sysname_" + return + fi + done + done + done + fi + [ -z "${!sysdistvar_}" ] && return 0 + for sysname_ in "${SYSNAMES[@]}"; do + array_copy sysdists_ "${sysname_}_SYSDISTS" + for sysdist_ in "${sysdists_[@]}"; do + if [ "$sysdist_" == "${!sysdistvar_}" ]; then + set_var "$sysnamevar_" "$sysname_" + return + fi + done + done + fi +} +function __fix_sysinfos_downward() { + local sysname_ sysdist_ sysver_ + + [ -z "${!sysnamevar_}" ] && return + + if [ -z "${!sysdistvar_}" ]; then + array_copy sysdists_ "${!sysnamevar_}_SYSDISTS" + for sysdist_ in "${sysdists_[@]}"; do + set_var "$sysdistvar_" "$sysdist_" + break + done + fi + [ -z "${!sysdistvar_}" ] && return + + if [ -z "${!sysvervar_}" ]; then + array_copy sysvers_ "${sysdistvar_}_SYSVERS" + for sysver_ in "${sysvers_[@]}"; do + set_var "$sysvervar_" "$sysver_" + break + done + fi +} +function ensure_sysinfos() { + local sysnamevar_="${1:-SYSNAME}" + local sysdistvar_="${2:-SYSDIST}" + local sysvervar_="${3:-SYSVER}" + [ -n "${!sysdistvar_}" ] && set_var "$sysdistvar_" "$(__get_sysdist_alias "${!sysdistvar_}")" + [ -n "${!sysvervar_}" ] && set_var "$sysvervar_" "$(__get_sysver_alias "${!sysvervar_}")" + __fix_sysinfos_upward + __fix_sysinfos_downward +} + +function check_sysinfos() { + local sysnamevar_="MYSYSNAME" + local sysdistvar_="MYSYSDIST" + local sysvervar_="MYSYSVER" + local bitsvar_="MYBITS" + local check_=sysname r_=0 + while [ -n "$1" ]; do + if [[ "$1" == -* ]]; then + [ "$1" == "-S" ] && { sysnamevar_="$2"; shift 2; continue; } + [ "$1" == "-D" ] && { sysdistvar_="$2"; shift 2; continue; } + [ "$1" == "-V" ] && { sysvervar_="$2"; shift 2; continue; } + [ "$1" == "-B" ] && { bitsvar_="$2"; shift 2; continue; } + [ "$r_" == "1" ] && break + [ "$1" == "-s" ] && check_=sysname + [ "$1" == "-d" ] && check_=sysdist + [ "$1" == "-v" ] && check_=sysver + [ "$1" == "-b" ] && check_=bits + r_=1 + shift + continue + fi + if [ "$check_" == "sysname" ]; then + if array_contains "$sysnamevar_" "$1"; then + r_=0 + check_=skip + fi + + elif [ "$check_" == "sysdist" ]; then + local mode_=exact value_="$1" + if [ "${value_%+}" != "$value_" ]; then + mode_=after + value_="${value_%+}" + elif [ "${value_%-}" != "$value_" ]; then + mode_=before + value_="${value_%-}" + fi + value_="$(__get_sysdist_alias "$value_")" + if [ "$mode_" == "exact" ]; then + if array_contains "$sysdistvar_" "$value_"; then + r_=0 + check_=skip + fi + elif [ "$mode_" == "after" ]; then + local sysdist_ + for sysdist_ in "${ALL_SYSDISTS[@]}"; do + if array_contains "$sysdistvar_" "$sysdist_"; then + r_=0 + check_=skip + elif [ "$sysdist_" == "$value_" ]; then + break + fi + done + elif [ "$mode_" == "before" ]; then + local sysdist_ found_ + for sysdist_ in "${ALL_SYSDISTS[@]}"; do + [ "$sysdist_" == "$value_" ] && found_=1 + if [ -n "$found_" ]; then + if array_contains "$sysdistvar_" "$sysdist_"; then + r_=0 + check_=skip + break + fi + fi + done + fi + + elif [ "$check_" == "sysver" ]; then + local mode_=exact value_="$1" + if [ "${value_%+}" != "$value_" ]; then + mode_=after + value_="${value_%+}" + elif [ "${value_%-}" != "$value_" ]; then + mode_=before + value_="${value_%-}" + fi + value_="$(__get_sysver_alias "$value_")" + if [ "$mode_" == "exact" ]; then + if array_contains "$sysvervar_" "$value_"; then + r_=0 + check_=skip + fi + elif [ "$mode_" == "after" ]; then + local sysver_ + for sysver_ in "${ALL_SYSVERS[@]}"; do + if array_contains "$sysvervar_" "$sysver_"; then + r_=0 + check_=skip + elif [ "$sysver_" == "$value_" ]; then + break + fi + done + elif [ "$mode_" == "before" ]; then + local sysver_ found_ + for sysver_ in "${ALL_SYSVERS[@]}"; do + [ "$sysver_" == "$value_" ] && found_=1 + if [ -n "$found_" ]; then + if array_contains "$sysvervar_" "$sysver_"; then + r_=0 + check_=skip + break + fi + fi + done + fi + + elif [ "$check_" == "bits" ]; then + if [ "$1" == "${!bitsvar_}" ]; then + r_=0 + check_=skip + fi + fi + shift + done + return $r_ +} +##@inc]../sysinfos +##@inc[../compat +# Code de support pour les architectures autre que Linux +##@require base +##@require sysinfos +uprovide compat +urequire base sysinfos + +if check_sysinfos -s macosx; then + function __rlnp() { local p="$1" np f; [ "${p#/}" == "$p" ] && p="$(pwd)/$p"; while [[ "$p" == *//* ]]; do p="${p//\/\///}"; done; p="${p%/}"; p="${p#/}"; np=; while [ -n "$p" ]; do if [[ "$p" == */* ]]; then f="${p%%/*}"; p="${p#*/}"; else f="$p"; p=; fi; if [ "$f" == . ]; then :; elif [ "$f" == .. ]; then if [[ "$np" == */* ]]; then np="${np%/*}"; else np=; fi; else [ -n "$np" ] && np="$np/"; np="$np$f"; fi; done; echo "/$np"; } + function readlinkm() { local p="$(__rlnp "$1")" np n; while [ -n "$p" ]; do local max=50; while [ -L "$p" -a $max -gt 0 ]; do n="$(readlink "$p")"; if [ "${n#/}" != "$n" ]; then p="$n"; else p="${p%/*}/$n"; fi; p="$(__rlnp "$p")"; max=$(($max-1)); done; [ -n "$np" ] && np="/$np"; if [[ "$p" == */* ]]; then np="${p##*/}$np"; p="${p%/*}"; else np="$p$np"; p=; fi; done; echo "/$np"; } + function _nl2lf() { awk '{ sub(/\r$/, ""); gsub(/\r/, "\n"); print }'; } + function _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; } + function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; } + function sedi() { sed -i '' "$@"; } + + function __po_check_options() { + local -a options args + local option value flag + if [ "${opts_#+}" != "$opts_" ]; then + while [ -n "$*" ]; do + if [ "$1" == "--" ]; then + shift + break + elif [[ "$1" == --* ]]; then + option="${1%%=*}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + else + value= + fi + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + elif [[ "$1" == -* ]]; then + option="${1:0:2}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + value="${1:2}" + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ -n "${1:2}" ]]; then + value="${1:2}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + else + break + fi + done + args=("$@") + elif [ "${opts_#-}" != "$opts_" ]; then + while [ -n "$*" ]; do + if [ "$1" == "--" ]; then + shift + break + elif [[ "$1" == --* ]]; then + option="${1%%=*}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + else + value= + fi + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + elif [[ "$1" == -* ]]; then + option="${1:0:2}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + value="${1:2}" + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ -n "${1:2}" ]]; then + value="${1:2}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + else + options=("${options[@]}" "$1") + shift + fi + done + args=("$@") + else + while [ -n "$*" ]; do + if [ "$1" == "--" ]; then + shift + break + elif [[ "$1" == --* ]]; then + option="${1%%=*}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + else + value= + fi + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ "$1" == *=* ]]; then + value="${1#--*=}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + elif [[ "$1" == -* ]]; then + option="${1:0:2}" + if flag="$(array_find options_ "$option" flags_)"; then + if [[ "$flag" == ::* ]]; then + value="${1:2}" + shift + options=("${options[@]}" "$option" "$value") + elif [[ "$flag" == :* ]]; then + if [[ -n "${1:2}" ]]; then + value="${1:2}" + shift + elif [ $# -gt 1 ]; then + value="$2" + shift 2 + else + echo "option requires an argument: $option" + return 1 + fi + options=("${options[@]}" "$option" "$value") + else + shift + options=("${options[@]}" "$option") + fi + else + echo "invalid option: $1" + return 1 + fi + + else + args=("${args[@]}" "$1") + shift + fi + done + args=("${args[@]}" "$@") + fi + quoted_args "${options[@]}" -- "${args[@]}" + return 0 + } + + function __pd_isleap() { + [ $(($1 % 4)) -eq 0 -a \( $(($1 % 100)) -ne 0 -o $(($1 % 400)) -eq 0 \) ] + } + function __pd_fix_month() { + local __pdfm_y="${!1}" __pdfm_m="${!2}" + let __pdfm_m=$__pdfm_m-1 + while [ $__pdfm_m -gt 11 ]; do + let __pdfm_m=$__pdfm_m-12 + let __pdfm_y=$__pdfm_y+1 + done + while [ $__pdfm_m -lt 0 ]; do + let __pdfm_m=$__pdfm_m+12 + let __pdfm_y=$__pdfm_y-1 + done + let __pdfm_m=$__pdfm_m+1 + eval "$1=$__pdfm_y; $2=$__pdfm_m" + } + __PD_MONTHDAYS=(0 31 28 31 30 31 30 31 31 30 31 30 31) + function __pd_monthdays() { + local y="$1" m="$2" mds + __pd_fix_month y m + mds="${__PD_MONTHDAYS[$m]}" + [ "$m" -eq 2 ] && __pd_isleap "$y" && let mds=$mds+1 + echo $mds + } + function __pd_fix_day() { + local __pdfd_y="${!1}" __pdfd_m="${!2}" __pdfd_d="${!3}" __pdfd_mds + let __pdfd_d=$__pdfd_d-1 + let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m) + while [ $__pdfd_d -gt $(($__pdfd_mds-1)) ]; do + let __pdfd_d=$__pdfd_d-$__pdfd_mds + let __pdfd_m=$__pdfd_m+1 + __pd_fix_month __pdfd_y __pdfd_m + let __pdfd_mds=$(__pd_monthdays $__pdfd_y $__pdfd_m) + done + while [ $__pdfd_d -lt 0 ]; do + let __pdfd_m=$__pdfd_m-1 + __pd_fix_month __pdfd_y __pdfd_m + let __pdfd_d=$__pdfd_d-$(__pd_monthdays $__pdfd_y $__pdfd_m) + done + let __pdfd_d=$__pdfd_d+1 + eval "$1=$__pdfd_y; $2=$__pdfd_m; $3=$__pdfd_d" + } + function __pd_fix_date() { + local __pdf_y="${!1}" __pdf_m="${!2}" __pdf_d="${!3}" + } + function parse_date() { + local value="$1" type="${2:-date}" + local d m y + eval "$(date +%d/%m/%Y | awk -F/ '{ + print "d=" $1 "; m=" $2 "; y=" $3 + }')" + if [ "${value#+}" != "$value" ]; then + d="$(($d+${value#+}))" + else + eval "$(<<<"$value" awkrun FS=/ dn="$dn" mn="$mn" yn="$yn" type="$type" '{ + d = $1 + 0; if (d < 1) d = dn + 0; + m = $2 + 0; if (m < 1) m = mn + 0; + if ($3 == "") y = yn + 0; + else { y = $3 + 0; if (y < 100) y = y + 2000; } + print "d=" d "; m=" m "; y=" y + }')" + fi + __pd_fix_month y m + __pd_fix_day y m d + case "$type" in + d|date) + awkrun d="$d" m="$m" y="$y" 'BEGIN { printf "%02i/%02i/%04i\n", d, m, y }' + ;; + l|ldap) + awkrun d="$d" m="$m" y="$y" 'BEGIN { printf "%04i%02i%02i000000+0400\n", y, m, d }' + ;; + esac + } + function myhost() { + hostname + } + function myhostname() { + hostname -s + } +fi +##@inc]../compat + +user="${1:-$USER}" +method="$2" + +case "$method" in +su) UTOOLS_USES_SU=1;; +sudo) UTOOLS_USES_SU=;; +esac +export UTOOLS_USES_SU + +if [ "$user" != "$USER" ]; then + is_root || run_as_root "$@" + if [ "$user" != "root" ]; then + run_as "$user" "$@" + fi +fi + +autoclean "$script" + +eval "cd ~$user"; mkdir -p .ssh; chmod 700 .ssh +cd .ssh; touch authorized_keys; chmod 600 authorized_keys +echo "$PUBKEYS" | while read pubkey; do + quietgrep "$pubkey" authorized_keys || + echo "$pubkey" >>authorized_keys +done diff --git a/ruinst b/ruinst index 05cc0c0..963c5e8 100755 --- a/ruinst +++ b/ruinst @@ -23,6 +23,9 @@ OPTIONS il est possible de faire la configuration avec '--configure root'. La commande serait alors $scriptname -h user@host --configure root + Si l'hôte distant n'a pas sudo ou si sudo n'est pas configuré, il faut + rajouter l'option --uses-su, e.g: + $scriptname -h user@host --configure root --uses-su -T tmproot Spécifier le répertoire temporaire sur l'hôte distant, comme par exemple /var/tmp. Cette option est utile pour les vservers, qui ont par défaut @@ -49,6 +52,7 @@ set_defaults pubkeys action=deploy confuser= +uses_su= tmproot= hosts=() SSH= @@ -57,6 +61,7 @@ parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -C action=configure \ --configure: '$set@ confuser;action=configure' \ + --uses-su uses_su=1 \ -T:,--tmproot: tmproot= \ -S: SSH= \ --force-make-archive force_make_archive=1 \ @@ -135,11 +140,11 @@ function prepare_pubkey_access() { # générer un script d'installation de clé avec la bonne clé ac_set_tmpfile IPKS awkrun PUBKEYS="$PUBKEYS" '{sub(/@@PUBKEYS@@/, PUBKEYS); } {print}' \ - <"$scriptdir/ulib/support/install-pubkeys.sh" >"$IPKS" + <"$ULIBDIR/support/install-pubkeys.sh" >"$IPKS" chmod +x "$IPKS" } function check_pubkey_access() { - local user= host="$1" confuser="$2" ipks="$3" + local user= host="$1" confuser="$2" ipks="$3" uses_su="$4" if [[ "$host" == *@* ]]; then user="${host%%@*}" host="${host#*@}" @@ -154,7 +159,7 @@ function check_pubkey_access() { if [ "$user" != "$confuser" ]; then enote "Vous pouvez être amené à entrer plusieurs fois le mot de passe de $user sur $host" scp -S "$SSH" -o StrictHostKeyChecking=no -o ConnectTimeout=2 -q "$ipks" "$user@$host:" && - "$SSH" -o ConnectTimeout=2 -qt "$user@$host" "./$(basename "$ipks") '$confuser'" || + "$SSH" -o ConnectTimeout=2 -qt "$user@$host" "./$(basename "$ipks") '$confuser' ${uses_su:+su}" || eerror "Impossible de copier la clé publique sur l'hôte distant" else "$SSH" -o StrictHostKeyChecking=no -o ConnectTimeout=2 -q "$user@$host" "PUBKEYS=$(quoted_sarg "$PUBKEYS")"' @@ -187,7 +192,7 @@ if [ "$action" == "configure" ]; then etitle -s "Configuration de l'accès par clé ssh" for host in "${hosts[@]}"; do - etitle "$host" check_pubkey_access "$host" "$confuser" "$IPKS" + etitle "$host" check_pubkey_access "$host" "$confuser" "$IPKS" "$uses_su" done eend exit 0