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
|
|
}
|