inc/ini-config
bf2ad701
 #!/bin/bash
 #
 # **inc/ini-config** - Configuration/INI functions
 #
 # Support for manipulating INI-style configuration files
 #
 # These functions have no external dependencies and no side-effects
 
 # Save trace setting
 INC_CONF_TRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 
 # Config Functions
 # ================
 
 # Append a new option in an ini file without replacing the old value
f44a024f
 # iniadd [-sudo] config-file section option value1 value2 value3 ...
bf2ad701
 function iniadd {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="-sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
     shift 3
 
7ae97298
     local values
     values="$(iniget_multiline $file $section $option) $@"
f44a024f
     iniset_multiline $sudo $file $section $option $values
bf2ad701
     $xtrace
 }
 
 # Comment an option in an INI file
f44a024f
 # inicomment [-sudo] config-file section option
bf2ad701
 function inicomment {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
 
f44a024f
     $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=.*$\)|#\1|" "$file"
bf2ad701
     $xtrace
 }
 
 # Get an option from an INI file
 # iniget config-file section option
 function iniget {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
     local file=$1
     local section=$2
     local option=$3
     local line
 
     line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
     echo ${line#*=}
     $xtrace
 }
 
 # Get a multiple line option from an INI file
 # iniget_multiline config-file section option
 function iniget_multiline {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
     local file=$1
     local section=$2
     local option=$3
     local values
 
     values=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { s/^$option[ \t]*=[ \t]*//gp; }" "$file")
     echo ${values}
     $xtrace
 }
 
 # Determinate is the given option present in the INI file
698796f1
 # ini_has_option [-sudo] config-file section option
bf2ad701
 function ini_has_option {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
698796f1
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
     local line
 
698796f1
     line=$($sudo sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
bf2ad701
     $xtrace
     [ -n "$line" ]
 }
 
 # Add another config line for a multi-line option.
 # It's normally called after iniset of the same option and assumes
 # that the section already exists.
 #
 # Note that iniset_multiline requires all the 'lines' to be supplied
 # in the argument list. Doing that will cause incorrect configuration
 # if spaces are used in the config values.
 #
f44a024f
 # iniadd_literal [-sudo] config-file section option value
bf2ad701
 function iniadd_literal {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
     local value=$4
 
92884ede
     if [[ -z $section || -z $option ]]; then
         $xtrace
         return
     fi
bf2ad701
 
     # Add it
f44a024f
     $sudo sed -i -e "/^\[$section\]/ a\\
bf2ad701
 $option = $value
 " "$file"
 
     $xtrace
 }
 
 # Remove an option from an INI file
f44a024f
 # inidelete [-sudo] config-file section option
bf2ad701
 function inidelete {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
 
92884ede
     if [[ -z $section || -z $option ]]; then
         $xtrace
         return
     fi
bf2ad701
 
     # Remove old values
f44a024f
     $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
bf2ad701
 
     $xtrace
 }
 
 # Set an option in an INI file
f44a024f
 # iniset [-sudo] config-file section option value
cede7874
 #  - if the file does not exist, it is created
bf2ad701
 function iniset {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
698796f1
     local sudo_option=""
f44a024f
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
698796f1
         sudo_option="-sudo "
f44a024f
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
     local value=$4
 
92884ede
     if [[ -z $section || -z $option ]]; then
         $xtrace
         return
     fi
bf2ad701
 
698796f1
     if ! $sudo grep -q "^\[$section\]" "$file" 2>/dev/null; then
bf2ad701
         # Add section at the end
f44a024f
         echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
bf2ad701
     fi
698796f1
     if ! ini_has_option $sudo_option "$file" "$section" "$option"; then
bf2ad701
         # Add it
f44a024f
         $sudo sed -i -e "/^\[$section\]/ a\\
bf2ad701
 $option = $value
 " "$file"
     else
ada886dd
         local sep
         sep=$(echo -ne "\x01")
bf2ad701
         # Replace it
c7c67658
         $sudo sed -i -e '/^\['${section}'\]/,/^\[.*\]/ s'${sep}'^\('"${option}"'[ \t]*=[ \t]*\).*$'${sep}'\1'"${value}"${sep} "$file"
bf2ad701
     fi
     $xtrace
 }
 
 # Set a multiple line option in an INI file
5509ed57
 # iniset_multiline [-sudo] config-file section option value1 value2 value3 ...
bf2ad701
 function iniset_multiline {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
 
     shift 3
     local values
     for v in $@; do
         # The later sed command inserts each new value in the line next to
         # the section identifier, which causes the values to be inserted in
         # the reverse order. Do a reverse here to keep the original order.
         values="$v ${values}"
     done
698796f1
     if ! $sudo grep -q "^\[$section\]" "$file"; then
bf2ad701
         # Add section at the end
f44a024f
         echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
bf2ad701
     else
         # Remove old values
f44a024f
         $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
bf2ad701
     fi
     # Add new ones
     for v in $values; do
f44a024f
         $sudo sed -i -e "/^\[$section\]/ a\\
bf2ad701
 $option = $v
 " "$file"
     done
     $xtrace
 }
 
 # Uncomment an option in an INI file
 # iniuncomment config-file section option
 function iniuncomment {
433a9b10
     local xtrace
     xtrace=$(set +o | grep xtrace)
bf2ad701
     set +o xtrace
f44a024f
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
bf2ad701
     local file=$1
     local section=$2
     local option=$3
f44a024f
     $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|[^ \t]*#[ \t]*\($option[ \t]*=.*$\)|\1|" "$file"
bf2ad701
     $xtrace
 }
 
135bd484
 # Get list of sections from an INI file
 # iniget_sections config-file
 function iniget_sections {
     local xtrace
     xtrace=$(set +o | grep xtrace)
     set +o xtrace
     local file=$1
 
     echo $(sed -ne "s/^\[\(.*\)\]/\1/p" "$file")
     $xtrace
 }
 
bb35715c
 # Set a localrc var
 function localrc_set {
     local file=$1
     local group="local"
     local conf="localrc"
     local section=""
     local option=$2
     local value=$3
     localconf_set "$file" "$group" "$conf" "$section" "$option" "$value"
 }
 
 # Check if local.conf has section.
 function localconf_has_section {
     local file=$1
     local group=$2
     local conf=$3
     local section=$4
     local sep
     sep=$(echo -ne "\x01")
     local line
     line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
         /\[${section}\]/p
     }" "$file")
     [ -n "$line" ]
 }
 
 # Check if local.conf has option.
 function localconf_has_option {
     local file=$1
     local group=$2
     local conf=$3
     local section=$4
     local option=$5
     local sep
     sep=$(echo -ne "\x01")
     local line
     if [[ -z "$section" ]]; then
         line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
             /${option}[ \t]*=.*$/p
         }" "$file")
     else
         line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
             /\[${section}\]/,/\[\[.*\]\]\|\[.*\]/{
                 /${option}[ \t]*=.*$/p}
         }" "$file")
     fi
     [ -n "$line" ]
 }
 
 # Update option in local.conf.
 function localconf_update_option {
     local sudo=$1
     local file=$2
     local group=$3
     local conf=$4
     local section=$5
     local option=$6
     local value=$7
     local sep
     sep=$(echo -ne "\x01")
     if [[ -z "$section" ]]; then
         $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
             s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
         }" "$file"
     else
         $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
             /\[${section}\]/,/\[\[.*\]\]\|\[.*\]/s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
         }" "$file"
     fi
 }
 
 # Add option in local.conf.
 function localconf_add_option {
     local sudo=$1
     local file=$2
     local group=$3
     local conf=$4
     local section=$5
     local option=$6
     local value=$7
     local sep
     sep=$(echo -ne "\x01")
     if [[ -z "$section" ]]; then
         $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} a $option=$value" "$file"
     else
         $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
             /\[${section}\]/ a $option=$value
         }" "$file"
     fi
 }
 
 # Add section and option in local.conf.
 function localconf_add_section_and_option {
     local sudo=$1
     local file=$2
     local group=$3
     local conf=$4
     local section=$5
     local option=$6
     local value=$7
     local sep
     sep=$(echo -ne "\x01")
     $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} {
         a [$section]
         a $option=$value
     }" "$file"
 }
 
 # Set an option in a local.conf file.
 # localconf_set [-sudo] config-file group conf-name section option value
 #  - if the file does not exist, it is created
 function localconf_set {
     local xtrace
     xtrace=$(set +o | grep xtrace)
     set +o xtrace
     local sep
     sep=$(echo -ne "\x01")
     local sudo=""
     if [ $1 == "-sudo" ]; then
         sudo="sudo "
         shift
     fi
     local file=$1
     local group=$2
     local conf=$3
     local section=$4
     local option=$5
     local value=$6
 
     if [[ -z $group || -z $conf || -z $option || -z $value ]]; then
         $xtrace
         return
     fi
 
     if ! grep -q "^\[\[${group}|${conf}\]\]" "$file" 2>/dev/null; then
         # Add meta section at the end if it does not exist
         echo -e "\n[[${group}|${conf}]]" | $sudo tee --append "$file" > /dev/null
         # Add section at the end
         if [[ -n "$section" ]]; then
             echo -e "[$section]" | $sudo tee --append "$file" > /dev/null
         fi
         # Add option at the end
         echo -e "$option=$value" | $sudo tee --append "$file" > /dev/null
     elif [[ -z "$section" ]]; then
         if ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
             # Add option
             localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
         else
             # Replace it
             localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
         fi
     elif ! localconf_has_section "$file" "$group" "$conf" "$section"; then
         # Add section and option in specified meta section
         localconf_add_section_and_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
     elif ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
         # Add option
         localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
     else
         # Replace it
         localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
     fi
     $xtrace
 }
 
bf2ad701
 # Restore xtrace
 $INC_CONF_TRACE
 
 # Local variables:
 # mode: shell-script
 # End: