1827 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			1827 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| 
 | |
| ##################################################
 | |
| # Gestion des fichiers
 | |
| 
 | |
| function filter_conf() {
 | |
|     # filtrer un fichier de configuration en enlevant les commentaires et les lignes vides
 | |
|     # $1==-m fusionner les lignes qui se terminent par \
 | |
|     local merge=cat
 | |
|     if [ "$1" == -m ]; then
 | |
|         merge='awk '\''substr($0, length($0)) == "\\" { while (substr($0, length($0)) == "\\") { getline nextline; $0 = substr($0, 1, length($0) - 1) nextline }; print; next } {print}'\'
 | |
|     fi
 | |
|     grep -v '^#' | grep -v '^$' | eval "$merge"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # Gestion des fichiers et répertoires temporaires
 | |
| function make_tempfile() {
 | |
|     # $1=template du fichier à créer
 | |
|     local mktmpdir=
 | |
|     if [ "$1" == "-d" ]; then
 | |
|         shift
 | |
|         mktmpdir=1
 | |
|     fi
 | |
|     local template="${1:-$TMPDIR/tmp.XXXXXX}"
 | |
|     local base="${template%%X*}"
 | |
|     local XXXs="${template#$base}"
 | |
|     [ -z "$XXXs" ] && XXXs="XXXXXX"
 | |
|     local nbX="${#XXXs}"
 | |
| 
 | |
|     local n="$$0" suff
 | |
|     while true; do
 | |
|         suff="$n"
 | |
|         while [ ${#suff} -lt $nbX ]; do suff="0$suff"; done
 | |
| 
 | |
|         tempfile="$base$suff"
 | |
|         if [ -n "$mktmpdir" ]; then
 | |
|             # répertoire temporaire
 | |
|             if [ ! -d "$tempfile" ]; then
 | |
|                 mkdir "$tempfile"
 | |
|                 break
 | |
|             fi
 | |
|         else
 | |
|             # fichier temporaire
 | |
|             if [ ! -f "$tempfile" ]; then
 | |
|                 touch "$tempfile"
 | |
|                 break
 | |
|             fi
 | |
|         fi
 | |
| 
 | |
|         n=$(($n + 1))
 | |
|     done
 | |
| 
 | |
|     echo "$tempfile"
 | |
| }
 | |
| 
 | |
| # autoclean: gérer une liste de fichiers temporaires à supprimer en fin de programme
 | |
| __ac_files=()
 | |
| function __ac_trap() {
 | |
|     local file_
 | |
|     for file_ in "${__ac_files[@]}"; do
 | |
|         [ -e "$file_" ] && rm -rf "$file_"
 | |
|     done
 | |
| }
 | |
| trap __ac_trap 1 3 15 EXIT
 | |
| function autoclean() {
 | |
|     # Ajouter $1..$n à la liste des fichiers à supprimer à la fin du programme
 | |
|     local file_
 | |
|     for file_ in "$@"; do
 | |
|         [ -n "$file_" ] && array_add __ac_files "$file_"
 | |
|     done
 | |
| }
 | |
| function ac_set_tmpfile() {
 | |
|     # Créer un fichier temporaire avec le motif $2, l'ajouter à la liste des
 | |
|     # fichiers à supprimer en fin de programme, et mettre sa valeur dans la
 | |
|     # variable $1
 | |
|     local tmpfile_="$(mktempf "$2")"
 | |
|     autoclean "$tmpfile_"
 | |
|     set_var "$1" "$tmpfile_"
 | |
| }
 | |
| function ac_set_tmpdir() {
 | |
|     # Créer un répertoire temporaire avec le motif $2, l'ajouter à la liste des
 | |
|     # fichiers à supprimer en fin de programme, et mettre sa valeur dans la
 | |
|     # variable $1
 | |
|     local tmpdir_="$(mktempd "$2")"
 | |
|     autoclean "$tmpdir_"
 | |
|     set_var "$1" "$tmpdir_"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # args: gestion d'un ensemble d'arguments
 | |
| 
 | |
| function read_args() {
 | |
|     # Lire les arguments et les mettre sur plusieurs lignes dans la variable
 | |
|     # dont le nom est donné dans $1. Ceci permet de façon fiable de traiter des
 | |
|     # arguments avec des espaces dedans.
 | |
| 
 | |
|     # note: cela suppose bien sûr que les arguments ne contiennent pas de retour
 | |
|     # à la ligne!!!
 | |
|     if [ -z "$1" ]; then return 1; fi
 | |
| 
 | |
|     local varname_="$1"; shift
 | |
|     local args_ arg_
 | |
| 
 | |
|     for arg_ in "$@"; do
 | |
|         args_="${args_:+$args_
 | |
| }$arg_"
 | |
|     done
 | |
|     set_var "$varname_" "$args_"
 | |
| }
 | |
| 
 | |
| function next_arg() {
 | |
|     # Soit la variable args dont le nom est donné dans $1, et la variable next
 | |
|     # dont le nom est donné dans $2. Mettre à jour next avec la première ligne
 | |
|     # de la variable args. Mettre à jour args avec le reste des lignes.
 | |
|     if [ -z "$1" -o -z "$2" ]; then return 1; fi
 | |
| 
 | |
|     local args_="$1"
 | |
|     local arg_="$2"
 | |
|     local line_ first_=1 first_line_ last_lines_
 | |
| 
 | |
|     eval "$((echo "${!args_}"; echo "---<eof>---") | while read line_; do
 | |
|         if [ "$line_" == "---<eof>---" ]; then
 | |
|             echo "first_line_=\"$(quote_arg "$first_line_")\"
 | |
| last_lines_=\"$(echo "$last_lines_" | awk '/.+/ { print; next }' | quote_string)\""
 | |
|         elif [ -n "$first_" ]; then
 | |
|             first_=
 | |
|             first_line_="$line_"
 | |
|         else
 | |
|             last_lines_="$last_lines_
 | |
| $line_"
 | |
|         fi
 | |
|     done)"
 | |
|     set_var "$args_" "$last_lines_"
 | |
|     set_var "$arg_" "$first_line_"
 | |
|     if [ -z "$first_line_" ]; then return 1; fi
 | |
| }
 | |
| 
 | |
| function get_option() {
 | |
|     # $1 est un argument de la forme "option:value"
 | |
|     # $2 est une liste d'options valides, séparées par des espaces
 | |
|     # $3 est un suffixe à rajouter au nom de variable
 | |
| 
 | |
|     # Si $1 est une option valide (de la forme 'option:value' avec option
 | |
|     # faisant partie de la liste (optionnelle) des options valides) alors mettre
 | |
|     # à jour la variable $option avec la valeur value. sinon, retourner un code
 | |
|     # d'erreur
 | |
| 
 | |
|     local arg_="$1"
 | |
|     local valid_options_="$2" valid_option_ is_valid_ option_ value_
 | |
|     local suffix_="$3"
 | |
| 
 | |
|     option_="$(expr "$arg_" : "\(..*\):")"
 | |
|     [ -z "$option_" ] && return 1
 | |
| 
 | |
|     if [ -n "$2" ]; then
 | |
|         # vérifier que $option est valide
 | |
|         is_valid_=
 | |
|         for valid_option_ in $valid_options_; do
 | |
|             if [ "$option_" == "$valid_option_" ]; then
 | |
|                 is_valid_=1
 | |
|                 break
 | |
|             fi
 | |
|         done
 | |
|         [ -z "$is_valid_" ] && return 1
 | |
|     fi
 | |
| 
 | |
|     value_="${1##$option_:}"
 | |
|     set_var "$option_$suffix_" "$value_"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # input: fonctions pour poser des question et saisir des valeurs
 | |
| 
 | |
| function ask_yesno() {
 | |
|     # $1=message, $2=default (N par défaut)
 | |
|     # Afficher le message $message suivi de [oN] ou [On] suivant que $default
 | |
|     # vaut O ou N. Retourner 0 si la réponse est oui, 1 sinon
 | |
| 
 | |
|     # Si default vaut C, alors la valeur par défaut dépend du niveau
 | |
|     # d'interactivité: N si on est interactif et O si on est pas interactif
 | |
| 
 | |
|     # Support de l'affichage de la question suivant le niveau d'interaction
 | |
|     # et/ou de verbosité Le message ne sera affiché que si le niveau
 | |
|     # d'interaction (ou de verbosité) courant est supérieur ou égal à celui qui
 | |
|     # est spécifié en argument. Sinon, la valeur par défaut est retournée
 | |
|     local r
 | |
|     check_verbosity "$1"; r=$?; [ $r -le 1 ] && shift
 | |
| 
 | |
|     local message="$1"
 | |
|     local prompt="[oN]"
 | |
|     local default="${2:-N}"
 | |
|     if [ "$default" == "C" ]; then
 | |
|         if [ $r -ne 1 ]; then
 | |
|             default=N
 | |
|         else
 | |
|             default=O
 | |
|         fi
 | |
|     fi
 | |
|     is_yes "$default" && prompt="[On]"
 | |
| 
 | |
|     if [ $r -ne 1 ]; then
 | |
|         if [ -n "$message" ]; then
 | |
|             tooenc_ "$message"
 | |
|         else
 | |
|             tooenc_ "Voulez-vous continuer?" "$UTF8"
 | |
|         fi
 | |
|         echo_ " $prompt "
 | |
|         uread r
 | |
|     else
 | |
|         r=
 | |
|     fi
 | |
| 
 | |
|     is_yes "${r:-$default}"
 | |
| }
 | |
| 
 | |
| function read_value() {
 | |
|     # $1=message, $2=varname, $3=default, $4=refuse_empty
 | |
|     # Afficher le message $message suivi la valeur par défaut [$default] si elle
 | |
|     # est non vide, puis lire la valeur donnée par l'utilisateur. Cette valeur
 | |
|     # doit être non vide si $refuse_empty est vrai (ce qui est le cas par
 | |
|     # défaut)
 | |
|     # La valeur saisie est placée dans la variable $varname (par défaut value)
 | |
| 
 | |
|     # note: les variables locales sont suffixées de _ pour éviter que $varname
 | |
|     # soit égal à une des variables locales.
 | |
| 
 | |
|     # Support l'affichage de la question suivant le niveau de "verbosité"
 | |
|     # Le message ne sera affiché que si le niveau de verbosité courant est
 | |
|     # supérieur ou égal à celui qui est spécifié en argument. Sinon, la valeur
 | |
|     # par défaut est retournée. (note: si l'utilisateur requière que la valeur
 | |
|     # soit non vide et que la valeur par défaut est vide, le script s'arrête
 | |
|     # avec une erreur)
 | |
|     local r_
 | |
|     check_verbosity "$1"; r_=$?; [ $r_ -le 1 ] && shift
 | |
| 
 | |
|     local message_="$1"
 | |
|     local varname_="${2:-value}"
 | |
|     local default_="$3"
 | |
|     local refuse_empty_="${4:-O}"
 | |
| 
 | |
|     local read_value_=
 | |
|     if [ $r_ -ne 1 ]; then
 | |
|         read_value_=1
 | |
|     elif [ -z "$default_" ] && is_yes "$refuse_empty_"; then
 | |
|         read_value_=1
 | |
|     fi
 | |
| 
 | |
|     if [ -n "$read_value_" ]; then
 | |
|         while true; do
 | |
|             if [ -n "$message_" ]; then
 | |
|                 tooenc_ "$message_"
 | |
|             else
 | |
|                 tooenc_ "Entrez la valeur" "$UTF8"
 | |
|             fi
 | |
|             [ -n "$default_" ] && tooenc_ " [$default_]"
 | |
|             echo_ ": "
 | |
|             uread r_; r_="${r_:-$default_}"
 | |
|             if [ -n "$r_" ] || ! is_yes "$refuse_empty_"; then
 | |
|                 set_var "$varname_" "$r_"
 | |
|                 return 0
 | |
|             fi
 | |
|         done
 | |
|     else
 | |
|         if [ -z "$default_" ] && is_yes "$refuse_empty_"; then
 | |
|             OENC="$UTF8" die "La valeur par défaut de $varname_ doit être non vide"
 | |
|         else
 | |
|             set_var "$varname_" "$default_"
 | |
|         fi
 | |
|     fi
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # menu: fonctions afficher un menu
 | |
| 
 | |
| function simple_menu() {
 | |
|     # $1=option_varname
 | |
|     # $2=options (une par ligne)
 | |
|     # $3..*=votre_choix:, titre_du_menu:, choix_par_defaut:
 | |
| 
 | |
|     # Afficher un menu dont les membres sont les lignes de $options. Un choix
 | |
|     # doit être saisi sous la forme num_option. L'option choisie est placée dans
 | |
|     # la variable $option_varname
 | |
| 
 | |
|     # note: les variables locales sont suffixées de _ pour éviter que
 | |
|     # $option_varname soit égal à une des variables locales.
 | |
| 
 | |
|     local tab_="	" # contient une tabulation
 | |
|     local i_ c_
 | |
|     local options_one_by_line_ options_ option_
 | |
|     local choice_ choice_option_
 | |
|     local option_varname_
 | |
|     local votre_choix_ titre_du_menu_ choix_par_defaut_
 | |
| 
 | |
|     # nom de la variable destination
 | |
|     option_varname_="$1"; shift
 | |
|     if [ -z "$option_varname_" ]; then
 | |
|         OENC="$UTF8" eerror "option_varname doit être spécifié"
 | |
|         return 1
 | |
|     fi
 | |
|     choix_par_defaut_="${!option_varname_}"
 | |
| 
 | |
|     # Construire le tableau des options
 | |
|     options_one_by_line_="$1"; shift
 | |
|     if [ -z "$options_one_by_line_" ]; then
 | |
|         OENC="$UTF8" eerror "options doit être non vide"
 | |
|         return 1
 | |
|     fi
 | |
|     i_=0
 | |
|     while next_arg options_one_by_line_ option_; do
 | |
|         options_[$i_]="$option_"
 | |
|         i_=$(($i_ + 1))
 | |
|     done
 | |
| 
 | |
|     # autres paramètres
 | |
|     while [ -n "$1" ]; do
 | |
|         ! get_option "$1" "votre_choix titre_du_menu choix_par_defaut" _ && break
 | |
|         shift
 | |
|     done
 | |
| 
 | |
|     c_=0
 | |
|     while true; do
 | |
|         if [ "$c_" == "0" ]; then
 | |
|             # Afficher le menu
 | |
|             [ -n "$titre_du_menu_" ] && tooenc "=== $titre_du_menu_ ==="
 | |
|             i_=1
 | |
|             for option_ in "${options_[@]}"; do
 | |
|                 if [ "$option_" == "$choix_par_defaut_" ]; then
 | |
|                     echo "$i_*- $option_"
 | |
|                 else
 | |
|                     echo "$i_ - $option_"
 | |
|                 fi
 | |
|                 i_=$(($i_ + 1)) 
 | |
|             done
 | |
|         fi
 | |
|         
 | |
|         # Afficher les choix
 | |
|         if [ -n "$votre_choix_" ]; then
 | |
|             tooenc_ "$votre_choix_"
 | |
|         else
 | |
|             tooenc_ "Entrez le numéro de l'option choisie" "$UTF8"
 | |
|         fi
 | |
|         echo_ ": "
 | |
|         uread choice_
 | |
| 
 | |
|         # valeur par défaut
 | |
|         if [ -z "$choice_" -a -n "$choix_par_defaut_" ]; then
 | |
|             choice_option_="$choix_par_defaut_"
 | |
|             break
 | |
|         fi
 | |
|         # vérifier la saisie
 | |
|         choice_option_="$(expr "$choice_" : "[ $tab_]*\([0-9]*\)")"
 | |
|         if [ -n "$choice_option_" ] && [ "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
 | |
|             # numéro d'option correct
 | |
|             choice_option_="${options_[$(($choice_option_ - 1))]}"
 | |
|             break
 | |
|         else
 | |
|             OENC="$UTF8" eerror "Numéro d'option incorrect"
 | |
|         fi
 | |
| 
 | |
|         c_=$(($c_ + 1))
 | |
|         if [ "$c_" == "5" ]; then
 | |
|             echo "" # sauter une ligne toutes les 4 tentatives
 | |
|             c_=0
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     set_var "$option_varname_" "$choice_option_"
 | |
| }
 | |
| 
 | |
| function actions_menu() {
 | |
|     # $1=action_varname, $2=option_varname
 | |
|     # $3=actions (séparées par des espaces), $4=options (une par ligne)
 | |
|     # $5..*=action_quitter:, action_par_defaut:, actions_vides:, votre_choix:,
 | |
|     #       titre_du_menu:, message_sans_options:
 | |
| 
 | |
|     # Afficher un menu dont les membres sont les lignes de $options. Sur
 | |
|     # chacunes de ces entrées de menu, les actions de $actions peuvent être
 | |
|     # appliquées. Un choix doit être saisi sous la forme [action]num_option. Si
 | |
|     # action n'est pas précisé, il s'agit de l'action par défaut qui est
 | |
|     # sélectionnée. Par défaut, action_par_defaut est la première action, et
 | |
|     # action_quitter (qui provoque la sortie du menu sans choix) est la dernière
 | |
|     # action
 | |
| 
 | |
|     # actions est une chaine d'éléments de la forme "k:Description" séparés par
 | |
|     # des espaces, où k est un lettre, et Description une description de
 | |
|     # l'action. Dans la chaine Description, les caractères '_' sont remplacés
 | |
|     # par des espaces pour l'affichage
 | |
| 
 | |
|     # l'action choisie est placée dans la variable $action_varname. l'option
 | |
|     # choisie est placée dans la variable $option_varname
 | |
| 
 | |
|     # note: les variables locales sont suffixées de _ pour éviter que
 | |
|     # $action_varname ou $option_varname soient égals à une des variables
 | |
|     # locales.
 | |
| 
 | |
|     local tab_="	" # contient une tabulation
 | |
|     local i_ c_ error_displayed_
 | |
|     local options_one_by_line_ options_ option_
 | |
|     local actions_sep_by_space_ actions_ action_ action_key_ action_name_ action_names_
 | |
|     local actions_vides_ action_vide_
 | |
|     local action_quitter_
 | |
|     local action_par_defaut_
 | |
|     local choice_ choice_ok_ choice_action_ choice_option_
 | |
|     local action_varname_ option_varname_
 | |
|     local sans_options_ message_sans_options_
 | |
| 
 | |
|     action_varname_="$1"; shift
 | |
|     option_varname_="$1"; shift
 | |
|     if [ -z "$action_varname_" -o -z "$option_varname_" ]; then
 | |
|         OENC="$UTF8" eerror "action_varname et option_varname doivent être spécifiés"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # actions possibles
 | |
|     actions_sep_by_space_="$1"; shift
 | |
|     if [ -z "$actions_sep_by_space_" ]; then
 | |
|         OENC="$UTF8" eerror "actions doit être non vide"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # Construire le tableau des options
 | |
|     options_one_by_line_="$1"; shift
 | |
|     if [ -n "$options_one_by_line_" ]; then
 | |
|         i_=0
 | |
|         while next_arg options_one_by_line_ option_; do
 | |
|             options_[$i_]="$option_"
 | |
|             i_=$(($i_ + 1))
 | |
|         done
 | |
|     else
 | |
|         sans_options_=1
 | |
|     fi
 | |
| 
 | |
|     # autres paramètres
 | |
|     while [ -n "$1" ]; do
 | |
|         ! get_option "$1" "actions_vides action_quitter action_par_defaut votre_choix titre_du_menu message_sans_options" _ && break
 | |
|         shift
 | |
|     done
 | |
|     if [ -n "$sans_options_" -a -z "$actions_vides_" ]; then
 | |
|         OENC="$UTF8" eerror "options doit être non vide"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # Construire le tableau des actions
 | |
|     i_=0
 | |
|     for action_ in $actions_sep_by_space_; do
 | |
|         action_key_="$(first_char "$action_")"
 | |
|         action_="$(last_chars "$action_")"
 | |
|         if [ "$(first_char "$action_")" == ":" ]; then
 | |
|             action_name_="$(last_chars "$action_")"
 | |
|             action_name_="${action_name_//_/ }"
 | |
|         else
 | |
|             action_name_="$action_key_"
 | |
|         fi
 | |
| 
 | |
|         [ -z "$action_par_defaut_" ] && action_par_defaut_="$action_key_"
 | |
|         [ "$action_key_" == "$action_par_defaut_" ] && action_name_="$action_name_*"
 | |
|         action_names_="${action_names_:+$action_names_/}$action_name_"
 | |
| 
 | |
|         actions_[$i_]="$(echo $action_key_ | awk '{print tolower($0)}')"
 | |
|         i_=$(($i_ + 1))
 | |
|     done
 | |
|     [ -z "$action_quitter_" ] && action_quitter_="$action_key_"
 | |
|     if [ "$action_par_defaut_" == "$action_quitter_" ]; then
 | |
|         OENC="$UTF8" eerror "action_par_defaut et action_quitter doivent être différents"
 | |
|         return 1
 | |
|     fi
 | |
|     actions_vides_="$actions_vides_ $action_quitter_"
 | |
| 
 | |
|     # Lecture des choix de l'utilisateur
 | |
|     c_=0
 | |
|     while true; do
 | |
|         if [ "$c_" == "0" ]; then
 | |
|             # Afficher le menu
 | |
|             [ -n "$titre_du_menu_" ] && tooenc "=== $titre_du_menu_ ==="
 | |
|             if [ -z "$sans_options_" ]; then
 | |
|                 i_=1
 | |
|                 for option_ in "${options_[@]}"; do
 | |
|                     tooenc "$i_ - $option_"
 | |
|                     i_=$(($i_ + 1))
 | |
|                 done
 | |
|             else
 | |
|                 if [ -n "$message_sans_options_" ]; then
 | |
|                     tooenc "$message_sans_options_"
 | |
|                 else
 | |
|                     tooenc "Pas d'options disponibles" "$UTF8"
 | |
|                 fi
 | |
|             fi
 | |
|         fi
 | |
|         
 | |
|         # Afficher les choix
 | |
|         tooenc_ "
 | |
| Actions disponibles: " "$UTF8"
 | |
|         tooenc "$action_names_"
 | |
|         if [ -n "$votre_choix_" ]; then
 | |
|             tooenc_ "$votre_choix_"
 | |
|         else
 | |
|             tooenc_ "Entrez le numéro de l'option choisie" "$UTF8"
 | |
|         fi
 | |
|         echo_ ": "
 | |
|         read choice_
 | |
|         
 | |
|         # vérifier la saisie
 | |
|         choice_option_="$(expr "$choice_" : "\([0-9]*\)")"
 | |
|         if [ -n "$choice_option_" ]; then
 | |
|             # on a donné le numéro de l'option sans l'action. retourner l'action par défaut
 | |
|             if [ -z "$sans_options_" -a "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
 | |
|                 # numéro d'option correct
 | |
|                 choice_option_="${options_[$(($choice_option_ - 1))]}"
 | |
|                 choice_action_="$action_par_defaut_"
 | |
|                 break
 | |
|             else
 | |
|                 OENC="$UTF8" eerror "Numéro d'option incorrect"
 | |
|             fi
 | |
| 
 | |
|         else
 | |
|             choice_action_="$(expr "$choice_" : "\([^ $tab_]\)")"
 | |
|             choice_ok_=
 | |
|             error_displayed_=
 | |
|             for action_ in "${actions_[@]}"; do
 | |
|                 if [ "$choice_action_" == "$action_" ]; then
 | |
|                     # action correcte
 | |
| 
 | |
|                     # est-ce une action vide (une action qui ne requière pas de numéro d'option)
 | |
|                     for action_vide_ in $actions_vides_; do
 | |
|                         if [ "$choice_action_" == "$action_vide_" ]; then
 | |
|                             # retourner comme option tous les arguments de
 | |
|                             # l'action vide, en trimant les espaces de début
 | |
|                             choice_option_="$(expr "$choice_" : "[^ $tab_][ $tab_]*\(.*\)")"
 | |
|                             choice_ok_=1
 | |
|                             break
 | |
|                         fi
 | |
|                     done
 | |
|                     [ -n "$choice_ok_" ] && break
 | |
| 
 | |
|                     # lire le numéro d'option associé à l'action
 | |
|                     choice_option_="$(expr "$choice_" : "[^ $tab_][ $tab_]*\([0-9]*\)")"
 | |
|                     if [ -n "$choice_option_" ] && [ "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
 | |
|                         # numéro d'option correct
 | |
|                         choice_option_="${options_[$(($choice_option_ - 1))]}"
 | |
|                         choice_ok_=1
 | |
|                     else
 | |
|                         OENC="$UTF8" eerror "Il faut spécifier un numéro d'option correct avec l'action"
 | |
|                         error_displayed_=1
 | |
|                     fi
 | |
|                     [ -n "$choice_ok_" ] && break
 | |
|                 fi
 | |
|             done
 | |
|             [ -n "$choice_ok_" ] && break
 | |
|             [ -z "$error_displayed_" ] && OENC="$UTF8" eerror "Action incorrecte"
 | |
|         fi
 | |
| 
 | |
|         c_=$(($c_ + 1))
 | |
|         if [ "$c_" == "5" ]; then
 | |
|             echo "" # sauter une ligne toutes les 4 tentatives
 | |
|             c_=0
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     set_var "$action_varname_" "$choice_action_"
 | |
|     set_var "$option_varname_" "$choice_option_"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # fileopts: opérations sur les fichiers
 | |
| 
 | |
| function file_get_vars() {
 | |
|     # lire les variables dans un fichier
 | |
|     local OENC="$UTF8"
 | |
|     local done_ prefix_ whole_file_ file_ vars_ var_ script_
 | |
| 
 | |
|     # traiter les arguments
 | |
|     done_=
 | |
|     while [ -z "$done_" ]; do
 | |
|         case "$1" in
 | |
|         --prefix|-p)
 | |
|             # prefixe pour la variable
 | |
|             prefix_="$2"
 | |
|             shift; shift
 | |
|             ;;
 | |
|         --whole-file|-w)
 | |
|             # lire les variables dans le fichier en entier, et pas seulement
 | |
|             # dans l'en-tête.
 | |
|             whole_file_=1
 | |
|             shift
 | |
|             ;;
 | |
|         *)
 | |
|             done_=1
 | |
|             ;;
 | |
|         esac
 | |
|     done
 | |
| 
 | |
|     # obtenir le nom du fichier
 | |
|     file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         # fichier inexistant
 | |
|         ewarn "Fichier inexistant: $file_"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # initialiser les valeurs par défaut
 | |
|     vars_=
 | |
|     while [ -n "$1" ]; do
 | |
|         var_="$1"; shift
 | |
|         vars_="${vars_:+$vars_ }$var_"
 | |
|         set_var "$var_" "$1"; shift
 | |
|     done
 | |
| 
 | |
|     # puis parcourir le fichier pour initialiser la valeur définitive des
 | |
|     # variables
 | |
|     if [ -z "$whole_file_" ]; then
 | |
|         script_="/^ *$/ { exit }
 | |
| "
 | |
|     fi
 | |
| 
 | |
|     for var_ in $vars_; do
 | |
|         script_="$script_
 | |
| "'$0 ~ "^ *#* *" prefix "'"$var_"'=" {
 | |
|     # enlever les caractères inutiles
 | |
|     sub(" *#* *" prefix "'"$var_"'=", "")
 | |
|     # enlever éventuellement les quotes autour de la valeur
 | |
|     if ($0 ~ /^".*" *$/) {
 | |
|         $0 = substr($0, 2) # premier quote
 | |
|         match($0, /" *$/)
 | |
|         $0 = substr($0, 1, RSTART - 1) # dernier quote
 | |
|     }
 | |
|     # remplacer dans les valeurs les occurences de quotes
 | |
|     gsub("\"", "\\\"")
 | |
|     # afficher la ligne à évaluer
 | |
|     print "'"$var_"'=\"" $0 "\""
 | |
| }
 | |
| '
 | |
|     done
 | |
| 
 | |
|     eval "$(uawk -v prefix="$prefix_" "$script_" <"$file_")"
 | |
| }
 | |
| 
 | |
| function file_set_vars() {
 | |
|     # écrire les variables dans un fichier. Le fichier *doit exister*
 | |
|     local OENC="$UTF8"
 | |
|     local done_ quote_ comment_ prefix_ whole_file_ file_ var_ script_
 | |
| 
 | |
|     # traiter les arguments
 | |
|     done_=
 | |
|     while [ -z "$done_" ]; do
 | |
|         case "$1" in
 | |
|         --quote-always|-q)
 | |
|             # toujours mettre les valeurs entre quotes
 | |
|             quote_=1
 | |
|             shift
 | |
|             ;;
 | |
|         --comment-prefix|-c)
 | |
|             # commentaire à préfixer
 | |
|             comment_="$2"
 | |
|             shift; shift
 | |
|             ;;
 | |
|         --prefix|-p)
 | |
|             # prefixe pour la variable
 | |
|             prefix_="$2"
 | |
|             shift; shift
 | |
|             ;;
 | |
|         --whole-file|-w)
 | |
|             # écrire les variables dans le fichier en entier, et pas seulement
 | |
|             # dans l'en-tête.
 | |
|             whole_file_=1
 | |
|             shift
 | |
|             ;;
 | |
|         *)
 | |
|             done_=1
 | |
|             ;;
 | |
|         esac
 | |
|     done
 | |
| 
 | |
|     # obtenir le nom du fichier
 | |
|     file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         # fichier inexistant
 | |
|         ewarn "Fichier inexistant: $file_"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # puis parcourir le fichier pour mettre à jour les valeurs
 | |
|     script_='BEGIN {
 | |
|     # faut-il mettre à jour les variables?
 | |
|     update_vars = 1'
 | |
|     for var_ in "$@"; do
 | |
|         script_="$script_
 | |
|     ${var_}_done = 0"
 | |
|     done
 | |
|     script_="$script_
 | |
| }"
 | |
| 
 | |
|     script_="$script_"'
 | |
| function quote_value_maybe(value) {
 | |
|     if (quote_always || index(value, " ") != 0) {
 | |
|         return "\"" value "\""
 | |
|     } else {
 | |
|         return value
 | |
|     }
 | |
| }
 | |
| 
 | |
| function write_all_remaining_vars() {'
 | |
|     for var_ in "$@"; do
 | |
|         value="${!var_}"
 | |
|         script_="$script_"'
 | |
|     if (! '"$var_"'_done) {
 | |
|         print comment prefix "'"$var_"'=" quote_value_maybe("'"${value//\"/\\\"}"'")
 | |
|         '"$var_"'_done = 1
 | |
|     }'
 | |
|     done
 | |
|     script_="$script_
 | |
| }"
 | |
| 
 | |
|     if [ -z "$whole_file_" ]; then
 | |
|         script_="$script_"'
 | |
| /^[ \t]*$/ {
 | |
|     write_all_remaining_vars()
 | |
|     update_vars = 0
 | |
| }'
 | |
|     fi
 | |
| 
 | |
|     script_="$script_"'
 | |
| update_vars && comment == "" && $0 ~ "^ *#* *.*=.*$" {
 | |
|     #comment = gensub("^( *#* *).*=.*$", "\\1", 1)
 | |
|     comment = ""
 | |
|     if (match($0, /^ *#* */) != 0) {
 | |
|         comment = substr($0, RSTART, RLENGTH)
 | |
|     }
 | |
| }'
 | |
| 
 | |
|     for var_ in "$@"; do
 | |
|         value="${!var_}"
 | |
|         script_="$script_"'
 | |
| update_vars && ! '"$var_"'_done && $0 ~ "^ *#* *" prefix "'"$var_"'=" {
 | |
|     #$0 = gensub("^( *#* *" prefix "'"$var_"'=).*$", "\\1", 1)
 | |
|     match($0, "^ *#* *" prefix "'"$var_"'=")
 | |
|     $0 = substr($0, RSTART, RLENGTH)
 | |
|     $0 = $0 quote_value_maybe("'"${value//\"/\\\"}"'")
 | |
|     print
 | |
|     '"$var_"'_done = 1
 | |
|     next
 | |
| }'
 | |
|     done
 | |
| 
 | |
|     script_="$script_"'
 | |
| {
 | |
|     print
 | |
| }
 | |
| END {
 | |
|     if (update_vars) {
 | |
|         write_all_remaining_vars()
 | |
|     }
 | |
| }'
 | |
| 
 | |
|     uawk -v quote_always="$quote_" -v comment="$comment_" -v prefix="$prefix_" "$script_" <"$file_" >"$file_.$$" &&
 | |
|     /bin/mv "$file_.$$" "$file_"
 | |
| }
 | |
| 
 | |
| function file_get_properties() {
 | |
|     # lire les propriétés d'un fichier de propriété java ou xml
 | |
|     if endswith "$1" .xml; then
 | |
|         file_get_xml_properties "$@"
 | |
|     else
 | |
|         file_get_java_properties "$@"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function file_set_properties() {
 | |
|     # écrire les propriétés d'un fichier de propriété java ou xml
 | |
|     local done_ create_
 | |
|     while [ -z "$done_" ]; do
 | |
|         case "$1" in
 | |
|         --create|-c)
 | |
|             create_=1
 | |
|             shift
 | |
|             ;;
 | |
|         *)
 | |
|             done_=1
 | |
|             ;;
 | |
|         esac
 | |
|     done
 | |
|     if endswith "$1" .xml; then
 | |
|         file_set_xml_properties ${create_:+-c} "$@"
 | |
|     else
 | |
|         file_set_java_properties ${create_:+-c} "$@"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| 
 | |
| function file_get_java_properties() {
 | |
|     # lire les propriétés d'un fichier de propriétés java. note: les noms de
 | |
|     # propriété java peuvent contenir le caractère "." mais pas les noms de
 | |
|     # variable bash. La conversion est faite automatiquement. Par exemple::
 | |
|     #    file_get_properties build.properties path.to.package "default value"
 | |
|     # charge la valeur de la propriété dans la variable path_to_package
 | |
| 
 | |
|     # $1=nom du fichier de propriété
 | |
|     # $2..n=propriétés qu'il faut lire et valeurs par défaut de ces propriétés
 | |
|     #   $__2*i  __=nom de la propriété
 | |
|     #   $__2*i+1__=valeur par défaut de la propriété si la valeur n'existe pas
 | |
|     #              dans le fichier
 | |
|     local OENC="$UTF8"
 | |
|     local file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         # fichier inexistant
 | |
|         ewarn "Fichier de propriété inexistant: $file_"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     local var_ sh_var_ awk_var_
 | |
|     local script
 | |
|     while [ -n "$1" ]; do
 | |
|         # pour chacune des variables...
 | |
|         var_="$1"; shift
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
| 
 | |
|         # initialiser la valeur par défaut
 | |
|         set_var "$sh_var_" "$1"; shift
 | |
| 
 | |
|         # et créer le script qui affichera sa valeur
 | |
|         script="$script"'
 | |
| $0 ~ "^[ \t]*'"$(quote_awk "$awkre_var_")"'=" {
 | |
|     # enlever les caractères de début
 | |
|     sub("^[ \t]*'"$(quote_awk "$awkre_var_")"'=", "")
 | |
|     value = $0
 | |
|     # éventuellement ajouter les lignes de continuation
 | |
|     while (substr(value, length(value), 1) == "\\") {
 | |
|         getline
 | |
|         sub("^[ \t]*", "")
 | |
|         value = substr(value, 1, length(value) - 1) $0
 | |
|     }
 | |
|     gsub("\"", "\\\"", value)
 | |
|     print "'"$sh_var_"'=\"" value "\""
 | |
| }
 | |
| '
 | |
|     done
 | |
| 
 | |
|     eval "$(awk "$script" <"$file_")"
 | |
| }
 | |
| 
 | |
| function file_set_java_properties() {
 | |
|     # écrire des propriétés dans un fichier de propriétés java.
 | |
| 
 | |
|     # $1=nom du fichier de propriété
 | |
|     # $2..n=propriétés qu'il faut écrire et valeurs de ces propriétés
 | |
|     #   $__2*i  __=nom de la propriété
 | |
|     #   $__2*i+1__=valeur de la propriété
 | |
|     # traiter les arguments
 | |
|     local OENC="$UTF8"
 | |
|     local done_ create_
 | |
|     while [ -z "$done_" ]; do
 | |
|         case "$1" in
 | |
|         --create|-c)
 | |
|             # créer le fichier s'il n'existe pas
 | |
|             create_=1
 | |
|             shift
 | |
|             ;;
 | |
|         *)
 | |
|             done_=1
 | |
|             ;;
 | |
|         esac
 | |
|     done
 | |
| 
 | |
|     local file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         if [ -n "$create_" ]; then
 | |
|             touch "$file_"
 | |
|         else
 | |
|             # fichier inexistant
 | |
|             ewarn "Fichier de propriété inexistant: $file_"
 | |
|             return 1
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     # récupérer les noms des propriétés et leur valeur
 | |
|     local var_ arg_ sh_var_ awkre_var_ value_
 | |
|     local -a vars_ values_
 | |
|     value_=vars_
 | |
|     for arg_ in "$@"; do
 | |
|         array_add "$value_" "$arg_"
 | |
|         if [ "$value_" == "vars_" ]; then
 | |
|             value_=values_
 | |
|         else
 | |
|             value_=vars_
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     # créer le script qui va parcourir le fichier pour mettre à jour les valeurs
 | |
|     script_="BEGIN {"
 | |
|     for var_ in "${vars_[@]}"; do
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         script_="$script_
 | |
|     ${sh_var_}_done = 0"
 | |
|     done
 | |
|     script_="$script_"'
 | |
| }
 | |
| function write_all_remaining_vars() {'
 | |
|     local i=0
 | |
|     while [ $i -lt ${#vars_[*]} ]; do
 | |
|         var_="${vars_[$i]}"
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
|         value_="${values_[$i]}"
 | |
| 
 | |
|         script_="$script_"'
 | |
|     if (! '"$sh_var_"'_done) {
 | |
|         print "'"$var_"'=" "'"${value_//\"/\\\"}"'"
 | |
|         '"$sh_var_"'_done = 1
 | |
|     }'
 | |
|         i=$((i + 1))
 | |
|     done
 | |
|     script_="$script_
 | |
| }"
 | |
| 
 | |
|     local i=0
 | |
|     while [ $i -lt ${#vars_[*]} ]; do
 | |
|         var_="${vars_[$i]}"
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
|         value_="${values_[$i]}"
 | |
|         script_="$script_"'
 | |
| ! '"$sh_var_"'_done && $0 ~ "^[ \t]*'"$awkre_var_"'=" {
 | |
|     #name = gensub("^([ \t]*'"$awkre_var_"'=).*$", "\\1", 1)
 | |
|     match($0, "^[ \t]*'"$awkre_var_"'=")
 | |
|     name = substr($0, RSTART, RLENGTH)
 | |
|     value = substr($0, length(name) + 1)
 | |
| 
 | |
|     while (substr(value, length(value), 1) == "\\") {
 | |
|         getline
 | |
|         value = value $0
 | |
|     }
 | |
|     line = name "'"${value_//\"/\\\"}"'"
 | |
|     prefix = ""
 | |
|     max_len = 75
 | |
|     if (length(line) > max_len) {
 | |
|         do {
 | |
|             print prefix substr(line, 1, max_len) "\\"
 | |
|             line = substr(line, max_len + 1)
 | |
|             prefix = "    "
 | |
|             max_len = 71
 | |
|         } while (length(line) > max_len)
 | |
|     }
 | |
|     print prefix line
 | |
|     '"$sh_var_"'_done = 1
 | |
|     next
 | |
| }'
 | |
|         i=$((i + 1))
 | |
|     done
 | |
| 
 | |
|     script_="$script_
 | |
| {
 | |
|     print
 | |
| }
 | |
| END {
 | |
|     write_all_remaining_vars()
 | |
| }"
 | |
| 
 | |
|     awk "$script_" <"$file_" >"$file_.$$" &&
 | |
|     /bin/mv "$file_.$$" "$file_"
 | |
| }
 | |
| 
 | |
| function file_get_xml_properties() {
 | |
|     # lire les propriétés d'un fichier de propriétés xml. Limitation: les
 | |
|     # propriétés ne doivent pas être continuées sur plusieurs lignes. Les
 | |
|     # propriétés doivent être écrites sous la forme::
 | |
|     #    <propname>propvalue</propname>
 | |
| 
 | |
|     # note: les noms de propriété java peuvent contenir le caractère "." mais
 | |
|     # pas les noms de variable bash. La conversion est faite
 | |
|     # automatiquement. Par exemple::
 | |
|     #    file_get_properties build.properties path.to.package "default value"
 | |
|     # charge la valeur de la propriété dans la variable path_to_package
 | |
| 
 | |
|     # $1=nom du fichier de propriété
 | |
|     # $2..n=propriétés qu'il faut lire et valeurs par défaut de ces propriétés
 | |
|     #   $__2*i  __=nom de la propriété
 | |
|     #   $__2*i+1__=valeur par défaut de la propriété si la valeur n'existe pas
 | |
|     #              dans le fichier
 | |
|     local OENC="$UTF8"
 | |
|     local file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         # fichier inexistant
 | |
|         ewarn "Fichier de propriété inexistant: $file_"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     local var_ sh_var_ awk_var_
 | |
|     local script
 | |
|     while [ -n "$1" ]; do
 | |
|         # pour chacune des variables...
 | |
|         var_="$1"; shift
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
| 
 | |
|         # initialiser la valeur par défaut
 | |
|         set_var "$sh_var_" "$1"; shift
 | |
| 
 | |
|         # et créer le script qui affichera sa valeur
 | |
|         script="$script"'
 | |
| $0 ~ /^[ \t]*<'"$awkre_var_"'>.*<\/'"$awkre_var_"'>/ {
 | |
|     sub(/^[ \t]*<'"$awkre_var_"'>/, "")
 | |
|     sub(/<\/'"$awkre_var_"'>.*$/, "")
 | |
|     gsub("\"", "\\\"", $0)
 | |
|     print "'"$sh_var_"'=\"" $0 "\""
 | |
| }
 | |
| '
 | |
|     done
 | |
| 
 | |
|     eval "$(awk "$script" <"$file_")"
 | |
| }
 | |
| 
 | |
| function file_set_xml_properties() {
 | |
|     # écrire des propriétés dans un fichier de propriétés java.
 | |
| 
 | |
|     # $1=nom du fichier de propriété
 | |
|     # $2..n=propriétés qu'il faut écrire et valeurs de ces propriétés
 | |
|     #   $__2*i  __=nom de la propriété
 | |
|     #   $__2*i+1__=valeur de la propriété
 | |
|     # traiter les arguments
 | |
|     local OENC="$UTF8"
 | |
|     local done_ create_
 | |
|     while [ -z "$done_" ]; do
 | |
|         case "$1" in
 | |
|         --create|-c)
 | |
|             # créer le fichier s'il n'existe pas
 | |
|             create_=1
 | |
|             shift
 | |
|             ;;
 | |
|         *)
 | |
|             done_=1
 | |
|             ;;
 | |
|         esac
 | |
|     done
 | |
| 
 | |
|     local file_="$1"; shift
 | |
|     if [ ! -f "$file_" ]; then
 | |
|         if [ -n "$create_" ]; then
 | |
|             touch "$file_"
 | |
|         else
 | |
|             # fichier inexistant
 | |
|             ewarn "Fichier de propriété inexistant: $file_"
 | |
|             return 1
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     # récupérer les noms des propriétés et leur valeur
 | |
|     local var_ arg_ sh_var_ awkre_var_ value_
 | |
|     local -a vars_ values_
 | |
|     value_=vars_
 | |
|     for arg_ in "$@"; do
 | |
|         array_add "$value_" "$arg_"
 | |
|         if [ "$value_" == "vars_" ]; then
 | |
|             value_=values_
 | |
|         else
 | |
|             value_=vars_
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     # créer le script qui va parcourir le fichier pour mettre à jour les valeurs
 | |
|     script_='BEGIN {
 | |
|     rootElement = ""'
 | |
|     for var_ in "${vars_[@]}"; do
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         script_="$script_
 | |
|     ${sh_var_}_done = 0"
 | |
|     done
 | |
|     script_="$script_"'
 | |
| }
 | |
| function write_all_remaining_vars() {'
 | |
|     local i=0
 | |
|     while [ $i -lt ${#vars_[*]} ]; do
 | |
|         var_="${vars_[$i]}"
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
|         value_="${values_[$i]}"
 | |
| 
 | |
|         script_="$script_"'
 | |
|     if (! '"$sh_var_"'_done) {
 | |
|         print "<'"$var_"'>'"${value_//\"/\\\"}"'</'"$var_"'>"
 | |
|         '"$sh_var_"'_done = 1
 | |
|     }'
 | |
|         i=$((i + 1))
 | |
|     done
 | |
|     script_="$script_
 | |
| }"'
 | |
| rootElement == "" {
 | |
|     match($0, /<.*>/)
 | |
|     element = substr($0, RSTART + 1, RLENGTH - 2)
 | |
|     firstChar = substr(element, 1, 1)
 | |
|     if (firstChar != "?" && firstChar != "!") {
 | |
|         rootElement = element
 | |
|     }
 | |
| }'
 | |
| 
 | |
|     local i=0
 | |
|     while [ $i -lt ${#vars_[*]} ]; do
 | |
|         var_="${vars_[$i]}"
 | |
|         sh_var_="${var_//./_}"    # nom de la variable shell traduite ("." --> "_")
 | |
|         sh_var_="${sh_var_//-/_}" #                                   ("-" --> "_")
 | |
|         awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
 | |
|         value_="${values_[$i]}"
 | |
|         script_="$script_"'
 | |
| rootElement != "" && ! '"$sh_var_"'_done && $0 ~ /^[ \t]*<'"$awkre_var_"'>.*<\/'"$awkre_var_"'>/ {
 | |
|     match($0, /^[ \t]*<'"$awkre_var_"'>/)
 | |
|     first = substr($0, RSTART, RLENGTH)
 | |
|     value = substr($0, length(first) + 1)
 | |
|     match(value, /<\/'"$awkre_var_"'>.*$/)
 | |
|     last = substr(value, RSTART, RLENGTH)
 | |
|     value = substr(value, 1, RSTART)
 | |
| 
 | |
|     print first "'"${value_//\"/\\\"}"'" last
 | |
|     '"$sh_var_"'_done = 1
 | |
|     next
 | |
| }'
 | |
|         i=$((i + 1))
 | |
|     done
 | |
| 
 | |
|     script_="$script_"'
 | |
| rootElement != "" && $0 ~ "</" rootElement ">" {
 | |
|     rootElement = ""
 | |
|     write_all_remaining_vars()
 | |
| }
 | |
| {
 | |
|     print
 | |
| }
 | |
| END {
 | |
|     write_all_remaining_vars()
 | |
| }'
 | |
| 
 | |
|     awk "$script_" <"$file_" >"$file_.$$" &&
 | |
|     /bin/mv "$file_.$$" "$file_"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # date: fonction pour afficher la date en français et au format RFC-822
 | |
| 
 | |
| function get_date_rfc822() {
 | |
|     if [ -n "$__legacy_date__" ]; then
 | |
|         LC_TIME=C date +"%a, %d %b %Y %H:%M:%S %Z"
 | |
|     else
 | |
|         date -R
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function get_date_fr() {
 | |
|     date +"%d/%m/%Y"
 | |
| }
 | |
| 
 | |
| function get_time_fr() {
 | |
|     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 > 31) d = nd;
 | |
|             if ($2 == "") m = nm;
 | |
|             else { m = $2 + 0; if (m < 1 || m > 12) 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"
 | |
|         ;;
 | |
|     *)
 | |
|         echo "$value"
 | |
|         ;;
 | |
|     esac
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # path: fonctions pour gérer les chemins
 | |
| 
 | |
| function abspath() {
 | |
|     # Retourner un chemin absolu vers $1. Si $2 est non nul et si $1 est un
 | |
|     # chemin relatif, alors $1 est exprimé par rapport à $2, sinon il est
 | |
|     # exprimé par rapport au répertoire courant.
 | |
|     local pwd="$(pwd)"
 | |
|     if [ -n "$2" ]; then
 | |
|         # tout d'abord, calculer le répertoire à partir duquel on exprime les
 | |
|         # chemin relatifs
 | |
|         if [ -d "$2" ]; then
 | |
|             pwd="$(cd "$2"; pwd)"
 | |
|         else
 | |
|             pwd="$(abspath "$2")"
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     if [ -e "$1" ]; then
 | |
|         local dn="$(dirname "$1")" bn="$(basename "$1")"
 | |
|         if [ "$bn" == "." ]; then
 | |
|             echo "$(cd "$pwd"; cd "$dn"; pwd)"
 | |
|         elif [ "$bn" == ".." ]; then
 | |
|             echo "$(cd "$pwd"; cd "$dn/.."; pwd)"
 | |
|         elif [ "$dn" == "/" ]; then
 | |
|             echo "/$bn"
 | |
|         else
 | |
|             echo "$(cd "$pwd"; cd "$dn"; pwd)/$bn"
 | |
|         fi
 | |
|     else
 | |
|         if first_char_is "$1" "/"; then
 | |
|             echo "$1"
 | |
|         else
 | |
|             echo "$pwd/$1"
 | |
|         fi
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function relpath() {
 | |
|     # Retourner le chemin relatif de $1 par rapport à $2. Si $2 n'est pas
 | |
|     # spécifié, on prend le répertoire courant. Si $1 ou $2 ne sont pas des
 | |
|     # répertoires absolus, il sont transformés en chemins absolus par rapport à
 | |
|     # $3.
 | |
|     # Si $1==$2, retourner une chaine vide
 | |
|     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
 | |
|         echo "${p#$cwd/}"
 | |
|     else
 | |
|         local rp
 | |
|         while [ -n "$cwd" -a "${p#$cwd/}" == "$p" ]; do
 | |
|             rp="${rp:+$rp/}.."
 | |
|             cwd="${cwd%/*}"
 | |
|         done
 | |
|         rp="$rp/${p#$cwd/}"
 | |
|         # ${rp%//} traite le cas $1==/
 | |
|         echo "${rp%//}"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function deref() {
 | |
|     # Retourner un chemin absolu vers le fichier $1, dans lequel
 | |
|     # toutes les composantes "lien symbolique" ont été supprimées.
 | |
|     local OENC="$UTF8"
 | |
| 
 | |
|     local max_deref=50
 | |
|     local file="$1"
 | |
|     while [ -L "$file" ]; do
 | |
|         basedir="$(dirname "$file")"
 | |
|         link="$(readlink "$file")"
 | |
|         if first_char_is "$link" "/"; then
 | |
|             # lien absolu
 | |
|             file="$link"
 | |
|         else
 | |
|             # lien relatif
 | |
|             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 path_if_test() {
 | |
|     # afficher un chemin si le fichier $2 existe (en utilisant l'opérateur $1)
 | |
|     # dans l'un des chemins absolus $4..n. si $3==relative, afficher le chemin
 | |
|     # relatif, sinon le chemin absolu. note: $3 peut être de la forme
 | |
|     # relative:path, auquel cas le chemin affiché est exprimé relativement à
 | |
|     # path
 | |
|     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
 | |
|             # on a un argument de la forme relative:path
 | |
|             reldir_="${reldir_#:}"
 | |
|             if [ -n "$reldir_" ]; then
 | |
|                 reldir_="${reldir_}/"
 | |
|             fi
 | |
|         else
 | |
|             # argument vide ou format non valide
 | |
|             reldir_=
 | |
|         fi
 | |
|     else
 | |
|         rel_=
 | |
|     fi
 | |
| 
 | |
|     while [ -n "$1" ]; do
 | |
|         local basedir_="$1"
 | |
|         if [ $op_ "$basedir_/$file_" ]; then
 | |
|             if [ -n "$rel_" ]; then
 | |
|                 echo "$reldir_$file_"
 | |
|             else
 | |
|                 echo "$basedir_/$file_"
 | |
|             fi
 | |
|             break
 | |
|         fi
 | |
|         shift
 | |
|     done
 | |
| }
 | |
| 
 | |
| function is_archive() {
 | |
|     # tester si l'extension d'un fichier indique que c'est une archive
 | |
|     local name="${1%.zip}"
 | |
|     name="${name%.tgz}"
 | |
|     name="${name%.tar.gz}"
 | |
|     name="${name%.tar}"
 | |
|     name="${name%.tar.bz2}"
 | |
|     name="${name%.jar}"
 | |
|     name="${name%.war}"
 | |
|     name="${name%.ear}"
 | |
|     [ "$name" != "$1" ]
 | |
| }
 | |
| function extract_archive() {
 | |
|     # Extraire le contenu de l'archive $1 dans le répertoire ${2:-.}
 | |
|     # Les autres arguments indiquent les fichiers à extraire
 | |
|     local arch="$1" destdir="${2:-.}"
 | |
|     shift; shift
 | |
|     if endswith "$arch" .zip; then
 | |
|         unzip -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
 | |
|         jar xf "$arch" -C "$destdir" "$@" || return
 | |
|     else
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| 
 | |
| 
 | |
| ##################################################
 | |
| # array: fonctions pour gérer des tableaux
 | |
| 
 | |
| # Afficher la commande permettant d'initialiser le tableau $1 avec les valeurs:
 | |
| # soit du tableau $2, soit de $3..$n si $2=="@"
 | |
| # S'il n'y a que l'argument $1, alors afficher la commande permettant de
 | |
| # recréer le tableau $1
 | |
| function set_array_cmd() {
 | |
|     [ $# -eq 1 ] && set -- "$1" "$1"
 | |
|     local s_ v_ f_
 | |
|     s_="$1=("; shift
 | |
|     if [ "$1" == "@" ]; then
 | |
|         shift
 | |
|     else
 | |
|         eval "set -- \"\${$1[@]}\""
 | |
|     fi
 | |
|     f_=1
 | |
|     for v_ in "$@"; do
 | |
|         [ -n "$f_" ] && f_= || s_="$s_ "
 | |
|         s_="$s_\"$(quote_arg "$v_")\""
 | |
|     done
 | |
|     s_="$s_)"
 | |
|     echo "$s_"
 | |
| }
 | |
| # Soit $1 un tableau à créer. Si $2=="@", créer le tableau $1 avec les valeurs
 | |
| # $3..$n. Sinon, créer le tableau $1 avec les valeurs du tableau $2.
 | |
| # Cette fonction n'existe que comme un pendant de set_var(), mais le véritable
 | |
| # intérêt est la fonction set_array_cmd(). cf array_copy() pour une version plus
 | |
| # efficace de la copie de tableaux
 | |
| function set_array() {
 | |
|     eval "$(set_array_cmd "$@")"
 | |
| }
 | |
| 
 | |
| function array_count() {
 | |
|     # retourner le nombre d'éléments du tableau $1
 | |
|     eval "echo \${#$1[*]}"
 | |
| }
 | |
| 
 | |
| function array_isempty() {
 | |
|     # tester si un tableau est vide
 | |
|     test $(array_count "$1") -eq 0
 | |
| }
 | |
|     
 | |
| function array_new() {
 | |
|     # créer un tableau vide dont le nom est $1
 | |
|     eval "$1=()"
 | |
| }
 | |
| 
 | |
| function array_add() {
 | |
|     # ajouter la valeur $2 au tableau dont le nom est $1
 | |
|     eval "$1=(\"\${$1[@]}\" \"$(quote_arg "$2")\")"
 | |
| }
 | |
| 
 | |
| # insérer la valeur $2 au début du tableau dont le nom est $1
 | |
| function array_ins() { eval "$1=(\"$(quote_arg "$2")\" \"\${$1[@]}\")"; }
 | |
| 
 | |
| function array_add_values() {
 | |
|     # Ajouter les valeurs $2 au tableau dont le nom est $1
 | |
|     # $2 est une liste de valeurs séparées par des espaces ou le caractère ':'
 | |
|     local array_="$1" value_
 | |
|     if [[ "$2" == *:* ]]; then
 | |
|         local IFS=:
 | |
|         set -- $2
 | |
|         unset IFS
 | |
|     else
 | |
|         set -- $2
 | |
|     fi
 | |
|     for value_ in "$@"; do
 | |
|         array_add "$array_" "$value_"
 | |
|     done
 | |
| }
 | |
| 
 | |
| function array_del() {
 | |
|     # supprimer les valeurs $2 du tableau dont le nom est $1
 | |
|     local arg_="$(quote_arg "$2")" value_
 | |
|     local -a array_
 | |
|     eval 'for value_ in "${'"$1"'[@]}"; do if [ "$value_" != "'"$arg_"'" ]; then array_add array_ "$value_"; fi; done'
 | |
|     array_copy "$1" array_
 | |
| }
 | |
| 
 | |
| function array_set() {
 | |
|     # ajouter la valeur $2 au tableau dont le nom est $1, si la valeur n'y est
 | |
|     # pas déjà. Retourner vrai si la valeur a été ajoutée
 | |
|     local value_="$(quote_arg "$2")" i_
 | |
|     eval "for i_ in \"\${$1[@]}\"; do if [ \"\$i_\" == \"$value_\" ]; then return 1; fi; done"
 | |
|     array_add "$1" "$2"
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function array_contains() {
 | |
|     # tester si le tableau dont le nom est $1 contient la valeur $2
 | |
|     local value_="$(quote_arg "$2")" i_
 | |
|     eval "for i_ in \"\${$1[@]}\"; do if [ \"\$i_\" == \"$value_\" ]; then return; fi; done"
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function array_copy() {
 | |
|     # copier le contenu du tableau $2 dans le tableau $1
 | |
|     eval "$1=(\"\${$2[@]}\")"
 | |
| }
 | |
| 
 | |
| function array_extend() {
 | |
|     # Ajouter le contenu du tableau $2 au tableau $1
 | |
|     eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")"
 | |
| }
 | |
| # dans le tableau $1, remplacer toutes les occurences de $2 par $3..*
 | |
| function array_replace() {
 | |
|     local srcname_="$1"; shift
 | |
|     local from_="$1"; shift
 | |
|     local -a dest_
 | |
|     local src_ v_
 | |
|     src_="$srcname_[@]"
 | |
|     for value_ in "${!src_}"; do
 | |
|         if [ "$value_" == "$from_" ]; then
 | |
|             dest_=("${dest_[@]}" "$@")
 | |
|         else
 | |
|             dest_=("${dest_[@]}" "$value_")
 | |
|         fi
 | |
|     done
 | |
|     array_copy "$srcname_" dest_
 | |
| }
 | |
| # Pour chacune des valeurs 'v' du tableau $1, appeler la fonction $2 avec les
 | |
| # arguments '$v $3..$n'
 | |
| function array_each() {
 | |
|     local an_="$1"; shift
 | |
|     local f_="$1"; shift
 | |
|     local a_="$an_[@]" v
 | |
|     for v_ in "${!a_}"; do
 | |
|         "$f_" "$v_" "$@"
 | |
|     done
 | |
| }
 | |
| # retourner la première valeur du tableau $1
 | |
| function first_value() { eval "echo \"\${$1[@]:0:1}\""; }
 | |
| # retourner la dernière valeur du tableau $1
 | |
| function last_value() { eval "echo \"\${$1[@]:\$((-1)):1}\""; }
 | |
| # copier le contenu du tableau $2 dans le tableau $1
 | |
| function array_copy() { eval "$1=(\"\${$2[@]}\")"; }
 | |
| # copier tous les valeurs du tableau $2(=$1) dans le tableau $1, excepté la dernière
 | |
| function array_copy_firsts() { eval "$1=(\"\${${2:-$1}[@]:0:\$((\${#${2:-$1}[@]}-1))}\")"; }
 | |
| function array_del_last() { array_copy_firsts "$1"; }
 | |
| # copier tous les valeurs du tableau $2(=$1) dans le tableau $1, excepté la première
 | |
| function array_copy_lasts() { eval "$1=(\"\${${2:-$1}[@]:1}\")"; }
 | |
| function array_del_first() { array_copy_lasts "$1"; }
 | |
| # ajouter le contenu du tableau $2 au tableau $1
 | |
| function array_extend() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")"; }
 | |
| # ajouter toutes les valeurs du tableau $2 dans le tableau $1, excepté la dernière
 | |
| function array_extend_firsts() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]:0:\$((\${#$2[@]}-1))}\")"; }
 | |
| # ajouter toutes les valeurs du tableau $2 dans le tableau $1, excepté la première
 | |
| function array_extend_lasts() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]:1}\")"; }
 | |
| # Pour chacune des valeurs 'v' du tableau $1, appeler la fonction $2 avec les
 | |
| # arguments '$v $3..$n', et remplacer la valeur par le résultat de la fonction
 | |
| function array_map() {
 | |
|     local an_="$1"; shift
 | |
|     local f_="$1"; shift
 | |
|     local a_="$an_[@]" v
 | |
|     local -a vs_
 | |
|     for v_ in "${!a_}"; do
 | |
|         vs_=("${vs_[@]}" "$("$f_" "$v_" "$@")")
 | |
|     done
 | |
|     array_copy "$an_" vs_
 | |
| }
 | |
| 
 | |
| function array_from_args() {
 | |
|     # créer le tableau dont le nom est $1 avec les arguments à partir de $2
 | |
|     local array_="$1"; shift
 | |
|     eval "$array_"'=("$@")'
 | |
| }
 | |
| 
 | |
| function array_from_file() {
 | |
|     # créer le tableau dont le nom est $1 avec les lignes du fichier $2
 | |
|     # si $3=all, ne pas supprimer les lignes vide ou de commentaire
 | |
|     eval "$(<"$2" uawk -v name="$1" -v all="$3" '
 | |
| BEGIN {
 | |
|     print name "=("
 | |
| }
 | |
| all != "all" && $0 ~ /^$/ { next }
 | |
| all != "all" && $0 ~ /^#/ { next }
 | |
| {
 | |
|     gsub(/'\''/, "'\'\\\\\'\''")
 | |
|     print "'\''" $0 "'\''"
 | |
| }
 | |
| END {
 | |
|     print ")"
 | |
| }')" #"
 | |
| }
 | |
| 
 | |
| function array_from_lines() {
 | |
|     # créer le tableau $1 avec chaque ligne de $2. Les lignes vides sont
 | |
|     # ignorés.
 | |
|     eval "$(<<<"$2" uawk -v name="$1" '
 | |
| BEGIN {
 | |
|     print name "=("
 | |
| }
 | |
| /^$/ { next }
 | |
| {
 | |
|     gsub(/'\''/, "'\'\\\\\'\''")
 | |
|     print "'\''" $0 "'\''"
 | |
| }
 | |
| END {
 | |
|     print ")"
 | |
| }')" #"
 | |
| }
 | |
| 
 | |
| function array_split() {
 | |
|     # créer le tableau $1 avec chaque élément de $2 (un ensemble d'éléments
 | |
|     # séparés par $3, qui vaut ':' par défaut). Les éléments vides sont
 | |
|     # ignorés. par exemple "a::b" est équivalent à "a:b"
 | |
|     eval "$(<<<"$2" uawk -v RS="" -v ORS="" '{ gsub("\r*\n$", ""); print }' |
 | |
| uawk -v name="$1" -v RS="${3:-:}" '
 | |
| BEGIN {
 | |
|     print name "=("
 | |
| }
 | |
| /^$/ { next }
 | |
| {
 | |
|     gsub(/'\''/, "'\'\\\\\'\''")
 | |
|     print "'\''" $0 "'\''"
 | |
| }
 | |
| END {
 | |
|     print ")"
 | |
| }')" #"
 | |
| }
 | |
| 
 | |
| function array_from_path() {
 | |
|     array_split "$1" "$2" ":"
 | |
| }
 | |
| 
 | |
| function array_join() {
 | |
|     # afficher le contenu du tableau dont le nom est $1 sous forme d'une liste
 | |
|     # de chemins séparés par $2
 | |
|     # Si $1=="@", alors les éléments du tableaux sont les arguments de la
 | |
|     # fonction à partir de $3
 | |
|     # Si $1!="@" et que le tableau est vide, afficher $3
 | |
|     # Si $1!="@", $4 et $5 sont des préfixes et suffixes à rajouter à chaque élément
 | |
|     local array_ line_ joined_ sep_="${2:-,}" pfix_ sfix_
 | |
|     if [ "$1" == "@" ]; then
 | |
|         array_="\$@"
 | |
|         shift; shift
 | |
|     else
 | |
|         array_="\${$1[@]}"
 | |
|         pfix_="$4"
 | |
|         sfix_="$5"
 | |
|     fi
 | |
|     eval 'for line_ in "'"$array_"'"; do joined_="${joined_:+$joined_'"$sep_"'}$pfix_$line_$sfix_"; done'
 | |
|     if [ -n "$joined_" ]; then
 | |
|         echo "$joined_"
 | |
|     elif [ "$array_" != "\$@" -a -n "$3" ]; then
 | |
|         echo "$3"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function array_to_lines() {
 | |
|     # afficher le tableau dont le nom est $1 sous forme de lignes
 | |
|     array_join "$1" "
 | |
| " "$2" "$3" "$4"
 | |
| }
 | |
| 
 | |
| function array_to_path() {
 | |
|     # afficher le tableau dont le nom est $1 sous forme d'une liste de chemins
 | |
|     # séparés par ':')
 | |
|     array_join "$1" ":" "$2" "$3" "$4"
 | |
| }
 | |
| 
 | |
| function array_enum_start() {
 | |
|     # Commencer l'énumération du tableau $1
 | |
|     [ -z "$1" ] && return 1
 | |
|     set_var_literal "${1}_enum_index" 0
 | |
| }
 | |
| 
 | |
| function array_enum_next() {
 | |
|     # Soit la variable array dont le nom est donné dans $1, et la variable next
 | |
|     # dont le nom est donné dans $2. Mettre à jour next avec l'élément
 | |
|     # $1_enum_index du tableau array, supprimer cet élément, et incrémenter
 | |
|     # $1_enum_index. Retourner faux s'il n'y a plus d'éléments dans le tableau
 | |
| 
 | |
|     local arrayname_="$1" varname_="$2"
 | |
|     [ -z "$arrayname_" -o -z "$varname_" ] && return 1
 | |
| 
 | |
|     eval "local count_=\${#$arrayname_[*]}"
 | |
|     [ $count_ -eq 0 ] && return 1
 | |
| 
 | |
|     # calculer l'index de départ
 | |
|     local index_="${arrayname_}_enum_index"
 | |
|     [ -z "${!index_}" ] && set_var_literal "$index_" 0
 | |
|     # lire la valeur
 | |
|     local item_="$arrayname_[${!index_}]"
 | |
|     set_var "$varname_" "${!item_}"
 | |
|     # la supprimer du tableau
 | |
|     unset "$item_"
 | |
|     # incrémenter le compteur
 | |
|     set_var_literal "$index_" $((${!index_} + 1))
 | |
| }
 | |
| 
 | |
| function __array_ls() {
 | |
|     # Lister les fichiers avec `list_$1 $3 $4...`, et les mettre dans le tableau $2
 | |
|     # Le tableau contient les chemins complets, par seulement les noms comme avec list_$1
 | |
|     local list_="list_${1:-all}"; shift
 | |
|     local arrayname_="$1"; shift
 | |
|     local basedir_="${1:-.}"; shift
 | |
|     local -a files_
 | |
|     array_from_lines files_ "$("$list_" "$basedir_" "$@")"
 | |
|     local file_
 | |
|     array_new "$arrayname_"
 | |
|     for file_ in "${files_[@]}"; do
 | |
|         array_add "$arrayname_" "$basedir_/$file_"
 | |
|     done
 | |
| }
 | |
| 
 | |
| function array_lsall() {
 | |
|     # Lister les fichiers avec `list_all $2 $3...`, et les mettre dans le tableau $1
 | |
|     # Le tableau contient les chemins complets, par seulement les noms comme avec list_all
 | |
|     __array_ls all "$@"
 | |
| }
 | |
| 
 | |
| function array_lsdirs() {
 | |
|     # Lister les fichiers avec `list_dirs $2 $3...`, et les mettre dans le tableau $1
 | |
|     # Le tableau contient les chemins complets, par seulement les noms comme avec list_dirs
 | |
|     __array_ls dirs "$@"
 | |
| }
 | |
| 
 | |
| function array_lsfiles() {
 | |
|     # Lister les fichiers avec `list_files $2 $3...`, et les mettre dans le tableau $1
 | |
|     # Le tableau contient les chemins complets, par seulement les noms comme avec list_files
 | |
|     __array_ls files "$@"
 | |
| }
 | |
| 
 | |
| ##################################################
 | |
| # Accès à une resource web
 | |
| 
 | |
| function _dumpurl_method_available() {
 | |
|     # $1=dumpurl_method
 | |
|     local m="$1"
 | |
|     if [ "$m" == "curl" ]; then
 | |
|         progexists curl || [ -n "$__curl_EXISTS__" ]
 | |
|     elif [ "$m" == "wget" ]; then
 | |
|         if progexists wget || [ -n "$__wget_EXISTS__" ]; then
 | |
|             # vérifier la version ce doit être >= 1.9
 | |
|             wget --version | grep "^GNU Wget" | awk '{
 | |
|     v = $0
 | |
|     major = 0
 | |
|     minor = 0
 | |
|     if (match(v, /[0-9][0-9]*/) != 0) {
 | |
|         major = substr(v, RSTART, RLENGTH) + 0
 | |
|         v = substr(v, RSTART + RLENGTH + 1)
 | |
|     }
 | |
|     if (match(v, /[0-9][0-9]*/) != 0) {
 | |
|         minor = substr(v, RSTART, RLENGTH) + 0
 | |
|         v = substr(v, RSTART + RLENGTH + 1)
 | |
|     }
 | |
| 
 | |
|     if (major >= 1 && minor >= 9) {
 | |
|         exit 0
 | |
|     } else {
 | |
|         exit 1
 | |
|     }
 | |
| }'
 | |
|         fi
 | |
|     else
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function dumpurl_method() {
 | |
|     if [ -z "$DUMPURL_METHOD" ]; then
 | |
|         local DUMPURL_METHOD
 | |
|         if _dumpurl_method_available curl; then
 | |
|             DUMPURL_METHOD=curl
 | |
|         elif _dumpurl_method_available wget; then
 | |
|             DUMPURL_METHOD=wget
 | |
|         ## XXX telnet non supporté pour le moment
 | |
|         #elif progexists telnet; then
 | |
|         #    DUMPURL_METHOD=telnet
 | |
|         fi
 | |
|     fi
 | |
|     echo "$DUMPURL_METHOD"
 | |
| }
 | |
| 
 | |
| function dumpurl_available() {
 | |
|     # retourner vrai si dumpurl est disponible (si wget ou curl sont trouvés)
 | |
|     _dumpurl_method_available "$(dumpurl_method)"
 | |
| }
 | |
| 
 | |
| function dumpurl() {
 | |
|     # afficher le résultat du téléchargement de l'url $1, ou une chaine vide si
 | |
|     # une erreur s'est produite.
 | |
|     # l'option -m choisit la méthode: GET ou POST (suivi de la chaine à envoyer)
 | |
|     # l'option -H permet d'ajouter des en-têtes
 | |
| 
 | |
|     local done= http_method=GET postdata headers header url no_proxy
 | |
|     local -a headers
 | |
|     while [ -n "$1" ]; do
 | |
|         case "$1" in
 | |
|         --)
 | |
|             shift
 | |
|             done=1
 | |
|             ;;
 | |
| 
 | |
|         -m)
 | |
|             shift
 | |
|             http_method="$1"
 | |
|             if [ "$http_method" == "POST" ]; then
 | |
|                 postdata="$2"
 | |
|                 shift
 | |
|             fi
 | |
|             ;;
 | |
| 
 | |
|         -H)
 | |
|             shift
 | |
|             array_add headers "$1: $2"
 | |
|             shift
 | |
|             ;;
 | |
| 
 | |
|         -X)
 | |
|             no_proxy=1
 | |
|             ;;
 | |
|             
 | |
|         -*)
 | |
|             #ewarn "option non reconnue: $1"
 | |
|             ;;
 | |
|             
 | |
|         *)
 | |
|             done=1
 | |
|             ;;
 | |
|         esac
 | |
|         [ -n "$done" ] && break
 | |
|         shift
 | |
|     done
 | |
|     url="$1"
 | |
| 
 | |
|     dumpurl_available || return 1
 | |
|     local dumpurl_method="$(dumpurl_method)"
 | |
| 
 | |
|     if [ "$dumpurl_method" == "curl" ]; then
 | |
|         curl="curl${no_proxy:+ -x ''}"
 | |
|         for header in "${headers[@]}"; do
 | |
|             curl="$curl --header \"$(quote_arg "$header")\""
 | |
|         done
 | |
|         if [ "$http_method" == "GET" ]; then
 | |
|             :
 | |
|         elif [ "$http_method" == "POST" ]; then
 | |
|             curl="$curl --data-binary \"$(quote_arg "$postdata")\""
 | |
|         else
 | |
|             # méthode inconnue
 | |
|             return 1
 | |
|         fi
 | |
|         curl="$curl -f -s \"$(quote_arg "$url")\""
 | |
| 
 | |
|         eval "$curl"
 | |
|         
 | |
|     elif [ "$dumpurl_method" == "wget" ]; then
 | |
|         wget="wget${no_proxy:+ --no-proxy}"
 | |
|         for header in "${headers[@]}"; do
 | |
|             wget="$wget --header=\"$(quote_arg "$header")\""
 | |
|         done
 | |
|         if [ "$http_method" == "GET" ]; then
 | |
|             :
 | |
|         elif [ "$http_method" == "POST" ]; then
 | |
|             wget="$wget --post-data=\"$(quote_arg "$postdata")\""
 | |
|         else
 | |
|             # méthode inconnue
 | |
|             return 1
 | |
|         fi
 | |
|         wget="$wget -q -O - \"$(quote_arg "$url")\""
 | |
| 
 | |
|         eval "$wget"
 | |
|         
 | |
|     # XXX pas encore implémenté
 | |
|     #elif [ "$dumpurl_method" == "telnet" ]; then
 | |
|     #    return 1
 | |
| 
 | |
|     else
 | |
|         return 1
 | |
|     fi
 | |
| }
 |