747 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			747 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
## Gestion des fichiers de configuration
 | 
						|
##@cooked nocomments
 | 
						|
##@require base
 | 
						|
uprovide conf
 | 
						|
urequire base
 | 
						|
 | 
						|
################################################################################
 | 
						|
# Gestion des fichiers de configuration où les directives sont de la forme
 | 
						|
# 'name=value' et où les commentaires débutent par '#'. C'est typiquement le cas
 | 
						|
# des scripts de profile du shell
 | 
						|
 | 
						|
# Note: #@$*! de MacOS X qui ne supporte pas \(expr\)\? dans sed.  Toutes les
 | 
						|
# lignes sed de la forme '/prefix\(expr\)\?suffix/s/from/to/g' sont remplacées
 | 
						|
# par une double expression
 | 
						|
#    '/prefixexprsuffix/s/from/to/g
 | 
						|
#    /prefixsuffix/s/from/to/g'
 | 
						|
 | 
						|
function conf_enable() {
 | 
						|
    # Dans le fichier de configuration $1, activer les paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Dans tous les cas, toutes les directives de ce nom sont recherchées et
 | 
						|
    # décommentées. Si value est précisée, les directives sont mises à jour. Si
 | 
						|
    # la directive ne figure pas dans le fichier, elle y est rajoutée à la fin
 | 
						|
    # avec la valeur spécifiée.
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value to
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        # Essayer d'abord de décommenter la valeur dans le fichier
 | 
						|
        if quietgrep "^[ $TAB]*##*[ $TAB]*\(export[ $TAB]*\)\?$name[ $TAB]*=" "$conf"; then
 | 
						|
            sedi "\
 | 
						|
/^[ $TAB]*##*[ $TAB]*export[ $TAB]*$name[ $TAB]*=/s/^[ $TAB]*##*\([ $TAB]*export[ $TAB]*\)/\\1/g
 | 
						|
/^[ $TAB]*##*[ $TAB]*$name[ $TAB]*=/s/^[ $TAB]*##*//g
 | 
						|
" "$conf"
 | 
						|
            modified=0
 | 
						|
        elif ! quietgrep "^[ $TAB]*\(export[ $TAB]*\)\?$name[ $TAB]*=" "$conf"; then
 | 
						|
            echo "$name=" >>"$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            # Ensuite, mettre à jour le fichier avec la valeur spécifiée
 | 
						|
            to="$(qseds "$value")"
 | 
						|
            sedi "\
 | 
						|
/^[ $TAB]*export[ $TAB]*$name[ $TAB]*=/s/^\([ $TAB]*export[ $TAB]*$name[ $TAB]*=[ $TAB]*\).*\$/\\1$to/
 | 
						|
/^[ $TAB]*$name[ $TAB]*=/s/^\([ $TAB]*$name[ $TAB]*=[ $TAB]*\).*\$/\\1$to/
 | 
						|
" "$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function conf_enableq() {
 | 
						|
    # Comme conf_enable(), mais s'assure que les valeurs sont quotées si
 | 
						|
    # nécessaire dans le fichier. Ceci permet de stocker des valeurs avec des
 | 
						|
    # espaces ou des caractères spéciaux.
 | 
						|
    local args arg name value
 | 
						|
    args=("$1"); shift
 | 
						|
    for arg in "$@"; do
 | 
						|
        splitvar "$arg" name value
 | 
						|
        array_add args "$name=$(qvalm "$value")"
 | 
						|
    done
 | 
						|
    conf_enable "${args[@]}"
 | 
						|
}
 | 
						|
 | 
						|
function conf_disable() {
 | 
						|
    # Dans le fichier de configuration $1, désactiver les paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Toutes les directives de ce noms sont recherchées et commentées. La valeur
 | 
						|
    # si elle est spécifiée, est ignorée. Si la directive ne figure pas dans le
 | 
						|
    # fichier, c'est un NOP.
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value from0 from1
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        # Essayer simplement de commenter la directive dans le fichier
 | 
						|
        from0="^[ $TAB]*export[ $TAB]*$name[ $TAB]*="
 | 
						|
        from1="^[ $TAB]*$name[ $TAB]*="
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            from0="$from0$(qseds "$value")\$"
 | 
						|
            from1="$from1$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        if quietgrep "$from" "$conf"; then
 | 
						|
            sedi "\
 | 
						|
/$from0/s/^/#/g
 | 
						|
/$from1/s/^/#/g
 | 
						|
" "$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
CONF_APPEND_SEP=:
 | 
						|
 | 
						|
function conf_append() {
 | 
						|
    # Dans le fichier de configuration $1, augmenter les valeurs des variables
 | 
						|
    # correspondant aux paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une variable du fichier de
 | 
						|
    # configuration, et doit être de la forme name=value
 | 
						|
    # Une ligne 'name="${name:+$name:}$value"' est générée à la fin du fichier
 | 
						|
    # de configuration.
 | 
						|
    # Par défaut, le séparateur CONF_APPEND_SEP vaut ':', mais il est possible
 | 
						|
    # de changer cette valeur, de façon globale
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        echo "$name=\"\${$name:+\$$name$CONF_APPEND_SEP}$(_qval "$value")\"" >>"$conf"
 | 
						|
        modified=0
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function conf_array_append() {
 | 
						|
    # Dans le fichier de configuration $1, augmenter les valeurs des variables
 | 
						|
    # de tableau correspondant aux paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une variable du fichier de
 | 
						|
    # configuration, et doit être de la forme name=value
 | 
						|
    # Une ligne name=("${name[@]}" "$value") est générée à la fin du fichier de
 | 
						|
    # configuration
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        if quietgrep "^[ $TAB]*\(export[ $TAB]*\)\?$name=(" "$conf"; then
 | 
						|
            # variable déjà existante
 | 
						|
            [ "$name" != "$param" ] || continue
 | 
						|
            echo "$name=(\"\${$name[@]}\" $(qvalm "$value"))" >>"$conf"
 | 
						|
        else
 | 
						|
            # nouvelle variable
 | 
						|
            if [ "$name" != "$param" ]; then
 | 
						|
                echo "$name=($(qvalm "$value"))" >>"$conf"
 | 
						|
            else
 | 
						|
                echo "$name=()" >>"$conf"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
        modified=0
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function conf_check() {
 | 
						|
    # Dans le fichier de configuration $1, tester si tous les paramètres $2..*
 | 
						|
    # sont présents.
 | 
						|
    # Chaque argument de cette fonction correspond à une variable du fichier de
 | 
						|
    # configuration, et doit être de la forme name[=value]
 | 
						|
    # Si une valeur est spécifiée, vérifier que le fichier contient la valeur
 | 
						|
    # correspondante. Sinon, tester uniquement la présence de la directive.
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        from="^[ $TAB]*\(export[ $TAB]*\)\?$name[ $TAB]*="
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            from="$from$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        quietgrep "$from" "$conf" || return 1
 | 
						|
    done
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
# Gestion des fichiers de configuration où les directives sont de la forme 'name
 | 
						|
# value', et où les commentaires débutent par '#'. C'est typiquement le cas des
 | 
						|
# fichiers de configuration d'apache
 | 
						|
 | 
						|
function aconf_enable() {
 | 
						|
    # Dans le fichier de configuration $1, activer les paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Toutes les directives de ce nom sont recherchées et décommentées, et la
 | 
						|
    # valeur mise à jour. Si la directive ne figure pas dans le fichier, elle y
 | 
						|
    # est rajoutée à la fin. A cause du mode opératoire, cette fonction ne
 | 
						|
    # convient pas pour les directives dont le nom peut apparaitre plusieurs
 | 
						|
    # fois dans le fichier
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value to
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        # Essayer d'abord de décommenter la valeur dans le fichier
 | 
						|
        if quietgrep "^[ $TAB]*##*[ $TAB]*$name[ $TAB]*" "$conf"; then
 | 
						|
            sedi "/^[ $TAB]*##*[ $TAB]*$name[ $TAB]*/s/^[ $TAB]*##*\([ $TAB]*\)/\\1/g" "$conf"
 | 
						|
            modified=0
 | 
						|
        elif ! quietgrep "^[ $TAB]*$name[ $TAB]*" "$conf"; then
 | 
						|
            echo "$name" >>"$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            # Ensuite, mettre à jour le fichier avec la valeur spécifiée
 | 
						|
            to="$(qseds "$value")"
 | 
						|
            sedi "\
 | 
						|
/^[ $TAB]*$name[ $TAB][ $TAB]*/s/^\([ $TAB]*$name[ $TAB]*\).*$/\\1$to/
 | 
						|
/^[ $TAB]*$name\$/s/^\([ $TAB]*$name\)\$/\\1 $to/" "$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function aconf_disable() {
 | 
						|
    # Dans le fichier de configuration $1, désactiver les paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Si la valeur est précisée, la directive correspondant à ce nom et cette
 | 
						|
    # valeur est recherchée et commentée. Sinon, toutes les directives de ce
 | 
						|
    # noms sont recherchées et commentées. Si la directive ne figure pas dans le
 | 
						|
    # fichier, c'est un NOP.
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        # Essayer simplement de commenter la valeur dans le fichier
 | 
						|
        from="^[ $TAB]*$name[ $TAB]*"
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            from="$from$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        if quietgrep "$from" "$conf"; then
 | 
						|
            sedi "/$from/"'s/^/#/g' "$conf"
 | 
						|
            modified=0
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function aconf_append() {
 | 
						|
    # Dans le fichier de configuration $1, ajouter des directives correspondant
 | 
						|
    # aux paramètres $2..*
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name=value
 | 
						|
    # Une ligne '$name $value' est ajoutée à la fin du fichier de configuration
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        echo "$name${value:+ $value}" >>"$conf"
 | 
						|
        modified=0
 | 
						|
    done
 | 
						|
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
function aconf_array_append() { aconf_append "$@"; }
 | 
						|
 | 
						|
function aconf_check() {
 | 
						|
    # Dans le fichier de configuration $1, tester si tous les paramètres $2..*
 | 
						|
    # sont présents.
 | 
						|
    # Chaque argument de cette fonction correspond à une variable du fichier de
 | 
						|
    # configuration, et doit être de la forme name[=value]
 | 
						|
    # Si une valeur est spécifiée, vérifier que le fichier contient la valeur
 | 
						|
    # correspondante. Sinon, tester uniquement la présence de la directive.
 | 
						|
    local conf="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local param name value from
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        from="^[ $TAB]*$name[ $TAB]*"
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            from="$from$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        quietgrep "$from" "$conf" || return 1
 | 
						|
    done
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
# Gestion des fichiers de configuration où les directives sont placées dans des
 | 
						|
# sections identifiées par une chaine de la forme [section]. Les directives sont
 | 
						|
# de la forme 'name=value', et les commentaires débutent par '#' ou ';'. C'est
 | 
						|
# typiquement le cas des fichiers de configuration de MySQL (my.cnf) et de PHP
 | 
						|
# (php.ini)
 | 
						|
 | 
						|
function mconf_enable() {
 | 
						|
    # Dans le fichier de configuration $1, activer les paramètres $3..* de la
 | 
						|
    # section $2
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Toutes les directives de ce nom sont recherchées et décommentées, et la
 | 
						|
    # valeur mise à jour. Si la directive ne figure pas dans le fichier, elle y
 | 
						|
    # est rajoutée à la fin. A cause du mode opératoire, cette fonction ne
 | 
						|
    # convient pas pour les directives dont le nom peut apparaitre plusieurs
 | 
						|
    # fois dans le fichier
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    # Cette fonction nécessite gawk et ignore la locale
 | 
						|
    local conf="$1"; shift
 | 
						|
    local section="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local script i param name value
 | 
						|
    script="BEGIN {
 | 
						|
  modified = 1
 | 
						|
  section = $(qawk "$section")
 | 
						|
  in_section = 0"
 | 
						|
    i=0
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        script="$script
 | 
						|
  names[$i] = $(qawk "$name")"
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            script="$script
 | 
						|
  hasvalues[$i] = 1
 | 
						|
  values[$i] = $(qawk "$value")"
 | 
						|
        else
 | 
						|
            script="$script
 | 
						|
  hasvalues[$i] = 0
 | 
						|
  values[$i] = \"\""
 | 
						|
        fi
 | 
						|
            script="$script
 | 
						|
  seen[$i] = 0"
 | 
						|
        let i=$i+1
 | 
						|
    done
 | 
						|
    script="$script"'
 | 
						|
}
 | 
						|
function write_unseen(write_section,                      wrote_section) {
 | 
						|
  for (i in seen) {
 | 
						|
    if (!seen[i]) {
 | 
						|
      if (write_section && !wrote_section) {
 | 
						|
        print "[" section "]"
 | 
						|
        wrote_section = 1
 | 
						|
      }
 | 
						|
      print names[i] "=" values[i]
 | 
						|
      seen[i] = 1
 | 
						|
      modified = 0
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
/^\[.*\]/ {
 | 
						|
  was_in_section = in_section
 | 
						|
  match($0, /^\[(.*)\]/, vs)
 | 
						|
  in_section = (vs[1] == section)
 | 
						|
  if (!in_section && was_in_section) {
 | 
						|
    write_unseen()
 | 
						|
  }
 | 
						|
}
 | 
						|
'
 | 
						|
    i=0
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        script="$script
 | 
						|
in_section && \$0 ~ /^[ $TAB]*((##*|;;*)[ $TAB]*)?$name[ $TAB]*=/ {
 | 
						|
  \$0 = gensub(/^[ $TAB]*(##*|;;*)[ $TAB]*($name[ $TAB]*=)/, \"\\\\2\", 1)
 | 
						|
  if (hasvalues[$i]) {
 | 
						|
    \$0 = gensub(/^([ $TAB]*$name[ $TAB]*=[ $TAB]*).*\$/, \"\\\\1\" values[$i], 1)
 | 
						|
  }
 | 
						|
  seen[$i] = 1
 | 
						|
  modified = 0
 | 
						|
}"
 | 
						|
        let i=$i+1
 | 
						|
    done
 | 
						|
    script="$script
 | 
						|
{ print }
 | 
						|
END {
 | 
						|
  write_unseen(!in_section)
 | 
						|
  exit modified
 | 
						|
}"
 | 
						|
 | 
						|
    local tmpfile; ac_set_tmpfile tmpfile
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
    if <"$conf" >"$tmpfile" cawk "$script"; then
 | 
						|
        cat "$tmpfile" >"$conf"
 | 
						|
        modified=0
 | 
						|
    fi
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    ac_clean "$tmpfile"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function mconf_disable() {
 | 
						|
    # Dans le fichier de configuration $1, désactiver les paramètres $3..* de la
 | 
						|
    # section $2.
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name[=value]
 | 
						|
    # Si la valeur est précisée, la directive correspondant à ce nom et cette
 | 
						|
    # valeur est recherchée et commentée. Sinon, toutes les directives de ce
 | 
						|
    # noms sont recherchées et commentées. Si la directive ne figure pas dans le
 | 
						|
    # fichier, c'est un NOP.
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    # Cette fonction nécessite gawk et ignore la locale
 | 
						|
    local conf="$1"; shift
 | 
						|
    local section="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local script match
 | 
						|
    script="BEGIN {
 | 
						|
  modified = 1
 | 
						|
  section = $(qawk "$section")
 | 
						|
  in_section = 0
 | 
						|
"
 | 
						|
    local param name value
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        match="${match:+$match || }\$0 ~ /^[ $TAB]*$name[ $TAB]*="
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            match="$match[ $TAB]*$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        match="$match/"
 | 
						|
    done
 | 
						|
    script="$script
 | 
						|
}"'
 | 
						|
/^\[.*\]/ {
 | 
						|
  match($0, /^\[(.*)\]/, vs)
 | 
						|
  in_section = (vs[1] == section)
 | 
						|
}
 | 
						|
in_section && ('"$match"') {
 | 
						|
  $0 = "#" $0
 | 
						|
  modified = 0
 | 
						|
}
 | 
						|
{ print }
 | 
						|
END {
 | 
						|
  exit modified
 | 
						|
}
 | 
						|
'
 | 
						|
 | 
						|
    local tmpfile; ac_set_tmpfile tmpfile
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
    if <"$conf" >"$tmpfile" cawk "$script"; then
 | 
						|
        cat "$tmpfile" >"$conf"
 | 
						|
        modified=0
 | 
						|
    fi
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    ac_clean "$tmpfile"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
 | 
						|
function mconf_append() {
 | 
						|
    # Dans le fichier de configuration $1, ajouter des directives correspondant
 | 
						|
    # aux paramètres $3..* dans la section $2
 | 
						|
    # Chaque argument de cette fonction correspond à une directive du fichier de
 | 
						|
    # configuration et doit être de la forme name=value
 | 
						|
    # Une ligne '$name = $value' est ajoutée à la fin de la section, qui est
 | 
						|
    # créée si nécessaire à la fin du fichier de configuration
 | 
						|
    # Retourner 0 si une modification a été faite dans le fichier, 1 sinon
 | 
						|
    # Cette fonction nécessite gawk et ignore la locale
 | 
						|
    local conf="$1"; shift
 | 
						|
    local section="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local script match
 | 
						|
    script="BEGIN {
 | 
						|
  modified = 1
 | 
						|
  section=$(qawk "$section")
 | 
						|
  in_section=0
 | 
						|
"
 | 
						|
    i=0
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        script="$script
 | 
						|
  names[$i] = $(qawk "$name")
 | 
						|
  values[$i] = $(qawk "$value")
 | 
						|
  seen[$i] = 0"
 | 
						|
        let i=$i+1
 | 
						|
    done
 | 
						|
    script="$script"'
 | 
						|
}
 | 
						|
function write_vars(write_section,                      wrote_section) {
 | 
						|
  for (i in seen) {
 | 
						|
    if (!seen[i]) {
 | 
						|
      if (write_section && !wrote_section) {
 | 
						|
        print "[" section "]"
 | 
						|
        wrote_section = 1
 | 
						|
      }
 | 
						|
      print names[i] "=" values[i]
 | 
						|
      seen[i] = 1
 | 
						|
      modified = 0
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
/^\[.*\]/ {
 | 
						|
  was_in_section = in_section
 | 
						|
  match($0, /^\[(.*)\]/, vs)
 | 
						|
  in_section = (vs[1] == section)
 | 
						|
  if (!in_section && was_in_section) {
 | 
						|
    write_vars()
 | 
						|
  }
 | 
						|
}
 | 
						|
{ print }
 | 
						|
END {
 | 
						|
  write_vars(!in_section)
 | 
						|
  exit modified
 | 
						|
}'
 | 
						|
 | 
						|
    local tmpfile; ac_set_tmpfile tmpfile
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
    if <"$conf" >"$tmpfile" cawk "$script"; then
 | 
						|
        cat "$tmpfile" >"$conf"
 | 
						|
        modified=0
 | 
						|
    fi
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    ac_clean "$tmpfile"
 | 
						|
    return $modified
 | 
						|
}
 | 
						|
function mconf_array_append() { mconf_append "$@"; }
 | 
						|
 | 
						|
function mconf_check() {
 | 
						|
    # Dans le fichier de configuration $1, tester si tous les paramètres $3..*
 | 
						|
    # sont présents dans la section $2
 | 
						|
    # Chaque argument de cette fonction correspond à une variable du fichier de
 | 
						|
    # configuration, et doit être de la forme name[=value]
 | 
						|
    # Si une valeur est spécifiée, vérifier que le fichier contient la valeur
 | 
						|
    # correspondante. Sinon, tester uniquement la présence de la directive.
 | 
						|
    # Cette fonction nécessite gawk et ignore la locale
 | 
						|
    local conf="$1"; shift
 | 
						|
    local section="$1"; shift
 | 
						|
    [ -n "$*" ] || return 1
 | 
						|
 | 
						|
    local script i param name value
 | 
						|
    script="BEGIN {
 | 
						|
  section = $(qawk "$section")
 | 
						|
  in_section = 0"
 | 
						|
    i=0
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        script="$script
 | 
						|
  names[$i] = $(qawk "$name")
 | 
						|
  values[$i] = $(qawk "$value")
 | 
						|
  seen[$i] = 0"
 | 
						|
        let i=$i+1
 | 
						|
    done
 | 
						|
    script="$script"'
 | 
						|
}
 | 
						|
/^\[.*\]/ {
 | 
						|
  match($0, /^\[(.*)\]/, vs)
 | 
						|
  in_section = (vs[1] == section)
 | 
						|
}
 | 
						|
'
 | 
						|
    i=0
 | 
						|
    for param in "$@"; do
 | 
						|
        splitvar "$param" name value
 | 
						|
        script="$script
 | 
						|
in_section && \$0 ~ /^[ $TAB]*$name[ $TAB]*="
 | 
						|
        if [ "$name" != "$param" ]; then
 | 
						|
            script="$script$(qseds "$value")\$"
 | 
						|
        fi
 | 
						|
        script="$script/ {
 | 
						|
  seen[$i] = 1
 | 
						|
}"
 | 
						|
        let i=$i+1
 | 
						|
    done
 | 
						|
    script="$script
 | 
						|
END {
 | 
						|
  for (i in seen) {
 | 
						|
    if (!seen[i]) exit 1
 | 
						|
  }
 | 
						|
  exit 0
 | 
						|
}"
 | 
						|
    <"$conf" cawk "$script"
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
# Gestion de fichiers de configuration générique
 | 
						|
 | 
						|
function gconf_addline() {
 | 
						|
    # USAGE
 | 
						|
    #     gconf_addline configfile -a BEGIN -z END NEWLINE
 | 
						|
    # Dans le fichier de configuration $1, ajouter la ligne NEWLINE entre les lignes
 | 
						|
    # BEGIN et END.
 | 
						|
    # -a BEGIN
 | 
						|
    #     Spécifier une expression pour matcher une ligne de type BEGIN. Si
 | 
						|
    #     cette option n'est pas spécifiée, on considère que le début de fichier
 | 
						|
    #     matche la ligne BEGIN: la ligne NEWLINE est ajoutée dès que possible.
 | 
						|
    #     Les lignes sont matchées dans l'ordre, i.e. avec '-a 1 -a 2', il faut
 | 
						|
    #     d'abord trouver la ligne 1 puis la ligne 2, sinon, le test n'est pas
 | 
						|
    #     concluant.
 | 
						|
    # -t LINE
 | 
						|
    #     Si après avoir matché toutes les lignes BEGIN, la ligne LINE est
 | 
						|
    #     rencontrée, alors considérer que la ligne à rajouter existe déjà et
 | 
						|
    #     qu'il ne faut pas la rajouter de nouveau
 | 
						|
    # -r LINE
 | 
						|
    #     Si après avoir matché toutes les lignes BEGIN, la ligne LINE est
 | 
						|
    #     rencontrée, alors considérer que la ligne à rajouter existe et qu'il
 | 
						|
    #     faut la mettre à jour. Supprimer la ligne existante et la remplacer
 | 
						|
    #     par la nouvelle ligne.
 | 
						|
    # -z END
 | 
						|
    #     Spécifier une expression pour matcher la ligne de type END. Que cette
 | 
						|
    #     option soit ou non spécifiée, on considère toujours que la fin de
 | 
						|
    #     fichier matche la ligne END. Ainsi, si END n'est pas trouvée, la ligne
 | 
						|
    #     NEWLINE est ajoutée à la fin du fichier.
 | 
						|
    #     Dès que la ligne END est rencontrée, et si aucun des tests -t ou -r
 | 
						|
    #     n'est concluant, alors ajouter la nouvelle ligne avant celle-ci
 | 
						|
    # -n MAX[=1]
 | 
						|
    #     Ajouter au plus MAX occurences de NEWLINE. Après avoir matché END, le
 | 
						|
    #     cycle recommence, au plus MAX-1 fois. Utiliser MAX=-1 pour désactiver
 | 
						|
    #     la limite
 | 
						|
    # Cette fonction nécessite gawk et ignore la locale
 | 
						|
    # Retourner 0 si l'ajout s'est fait correctement. Retourner 1 si BEGIN n'a
 | 
						|
    # pas été trouvé, et donc aucun ajout n'a été effectué. Retourner 2 si une
 | 
						|
    # erreur quelconque s'est produite
 | 
						|
 | 
						|
    eval "$(utools_local)"
 | 
						|
    local -a beginlines newlines
 | 
						|
    local testline replaceline endline max
 | 
						|
    parse_opts "${PRETTYOPTS[@]}" \
 | 
						|
        -a:,--begin: beginlines \
 | 
						|
        -t:,--test: testline= \
 | 
						|
        -r:,--replace: replaceline= \
 | 
						|
        -z:,--end: endline= \
 | 
						|
        -n:,--max: max= \
 | 
						|
        @ args -- "$@" && set -- "${args[@]}" || {
 | 
						|
        eerror "$args"
 | 
						|
        return 2
 | 
						|
    }
 | 
						|
    conf="$1"; shift
 | 
						|
    [ -n "$conf" ] || {
 | 
						|
        eerror "Vous devez spécifier le fichier à modifier"
 | 
						|
        return 2
 | 
						|
    }
 | 
						|
    [ -f "$conf" ] || {
 | 
						|
        eerror "$conf: fichier introuvable"
 | 
						|
        return 2
 | 
						|
    }
 | 
						|
    [ $# -gt 0 ] || {
 | 
						|
        eerror "Vous devez spécifier la ligne à rajouter"
 | 
						|
        return 2
 | 
						|
    }
 | 
						|
    [ -n "$max" ] || max=1
 | 
						|
    newlines=("$@")
 | 
						|
 | 
						|
    # générer le script
 | 
						|
    local script="$(awkdef -f beginlines[@] testline="$testline" replaceline="$replaceline" endline="$endline" max:int="$max" newlines[@])"'
 | 
						|
BEGIN {
 | 
						|
  searchindex = 1
 | 
						|
  found = 0
 | 
						|
  writeline = 1
 | 
						|
  if (beginlines_count == 0) found = 1
 | 
						|
  modified = 0
 | 
						|
}
 | 
						|
function writelines_maybe() {
 | 
						|
  if (writeline) {
 | 
						|
    for (i = 1; i <= newlines_count; i++) {
 | 
						|
      print newlines[i]
 | 
						|
    }
 | 
						|
    writeline = 0
 | 
						|
    modified = 1
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
max != 0 && !found && searchindex <= length(beginlines) && $0 ~ beginlines[searchindex] {
 | 
						|
  searchindex++
 | 
						|
  if (searchindex > length(beginlines)) {
 | 
						|
    found = 1
 | 
						|
  }
 | 
						|
  print; next
 | 
						|
}
 | 
						|
max != 0 && found && writeline && testline != "" && $0 ~ testline {
 | 
						|
  writeline = 0
 | 
						|
  print; next
 | 
						|
}
 | 
						|
max != 0 && found && writeline && replaceline != "" && $0 ~ replaceline {
 | 
						|
  writelines_maybe()
 | 
						|
  next
 | 
						|
}
 | 
						|
max != 0 && found && writeline && endline != "" && $0 ~ endline {
 | 
						|
  writelines_maybe()
 | 
						|
  searchindex = 1
 | 
						|
  found = 0
 | 
						|
  writeline = 1
 | 
						|
  if (max > 0) max--
 | 
						|
  print; next
 | 
						|
}
 | 
						|
{ print }
 | 
						|
END {
 | 
						|
  if (max != 0 && found && writeline) {
 | 
						|
    writelines_maybe()
 | 
						|
  }
 | 
						|
  if (modified) exit 0
 | 
						|
  else exit 1
 | 
						|
}
 | 
						|
'
 | 
						|
    edebug "$script"
 | 
						|
 | 
						|
    # traiter le fichier
 | 
						|
    local tmpfile; ac_set_tmpfile tmpfile
 | 
						|
    local mode="$(fix_mode "$conf")"
 | 
						|
    local modified=1
 | 
						|
    if <"$conf" >"$tmpfile" cawk "$script"; then
 | 
						|
        cat "$tmpfile" >"$conf"
 | 
						|
        modified=0
 | 
						|
    fi
 | 
						|
    unfix_mode "$conf" "$mode"
 | 
						|
    ac_clean "$tmpfile"
 | 
						|
    return $modified
 | 
						|
}
 |