blob: f65e42d3a5b8459f7da47bc90932e1f8c664df48 [file] [log] [blame]
Dean Troyerbf2ad702015-03-09 15:16:10 -05001#!/bin/bash
2#
3# **inc/ini-config** - Configuration/INI functions
4#
5# Support for manipulating INI-style configuration files
6#
7# These functions have no external dependencies and no side-effects
8
9# Save trace setting
10INC_CONF_TRACE=$(set +o | grep xtrace)
11set +o xtrace
12
13
14# Config Functions
15# ================
16
17# Append a new option in an ini file without replacing the old value
Ian Wienandf44a0242015-07-22 10:34:47 +100018# iniadd [-sudo] config-file section option value1 value2 value3 ...
Dean Troyerbf2ad702015-03-09 15:16:10 -050019function iniadd {
Ian Wienand433a9b12015-10-07 13:29:31 +110020 local xtrace
21 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -050022 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +100023 local sudo=""
24 if [ $1 == "-sudo" ]; then
25 sudo="-sudo "
26 shift
27 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -050028 local file=$1
29 local section=$2
30 local option=$3
31 shift 3
32
Ian Wienand7ae97292016-02-16 14:50:53 +110033 local values
34 values="$(iniget_multiline $file $section $option) $@"
Ian Wienandf44a0242015-07-22 10:34:47 +100035 iniset_multiline $sudo $file $section $option $values
Dean Troyerbf2ad702015-03-09 15:16:10 -050036 $xtrace
37}
38
39# Comment an option in an INI file
Ian Wienandf44a0242015-07-22 10:34:47 +100040# inicomment [-sudo] config-file section option
Dean Troyerbf2ad702015-03-09 15:16:10 -050041function inicomment {
Ian Wienand433a9b12015-10-07 13:29:31 +110042 local xtrace
43 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -050044 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +100045 local sudo=""
46 if [ $1 == "-sudo" ]; then
47 sudo="sudo "
48 shift
49 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -050050 local file=$1
51 local section=$2
52 local option=$3
53
Ian Wienandf44a0242015-07-22 10:34:47 +100054 $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=.*$\)|#\1|" "$file"
Dean Troyerbf2ad702015-03-09 15:16:10 -050055 $xtrace
56}
57
58# Get an option from an INI file
59# iniget config-file section option
60function iniget {
Ian Wienand433a9b12015-10-07 13:29:31 +110061 local xtrace
62 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -050063 set +o xtrace
64 local file=$1
65 local section=$2
66 local option=$3
67 local line
68
69 line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
70 echo ${line#*=}
71 $xtrace
72}
73
74# Get a multiple line option from an INI file
75# iniget_multiline config-file section option
76function iniget_multiline {
Ian Wienand433a9b12015-10-07 13:29:31 +110077 local xtrace
78 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -050079 set +o xtrace
80 local file=$1
81 local section=$2
82 local option=$3
83 local values
84
85 values=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { s/^$option[ \t]*=[ \t]*//gp; }" "$file")
86 echo ${values}
87 $xtrace
88}
89
90# Determinate is the given option present in the INI file
Yi Wang698796f2018-12-14 10:35:26 +080091# ini_has_option [-sudo] config-file section option
Dean Troyerbf2ad702015-03-09 15:16:10 -050092function ini_has_option {
Ian Wienand433a9b12015-10-07 13:29:31 +110093 local xtrace
94 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -050095 set +o xtrace
Yi Wang698796f2018-12-14 10:35:26 +080096 local sudo=""
97 if [ $1 == "-sudo" ]; then
98 sudo="sudo "
99 shift
100 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500101 local file=$1
102 local section=$2
103 local option=$3
104 local line
105
Yi Wang698796f2018-12-14 10:35:26 +0800106 line=$($sudo sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
Dean Troyerbf2ad702015-03-09 15:16:10 -0500107 $xtrace
108 [ -n "$line" ]
109}
110
111# Add another config line for a multi-line option.
112# It's normally called after iniset of the same option and assumes
113# that the section already exists.
114#
115# Note that iniset_multiline requires all the 'lines' to be supplied
116# in the argument list. Doing that will cause incorrect configuration
117# if spaces are used in the config values.
118#
Ian Wienandf44a0242015-07-22 10:34:47 +1000119# iniadd_literal [-sudo] config-file section option value
Dean Troyerbf2ad702015-03-09 15:16:10 -0500120function iniadd_literal {
Ian Wienand433a9b12015-10-07 13:29:31 +1100121 local xtrace
122 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -0500123 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +1000124 local sudo=""
125 if [ $1 == "-sudo" ]; then
126 sudo="sudo "
127 shift
128 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500129 local file=$1
130 local section=$2
131 local option=$3
132 local value=$4
133
Ian Wienand92884ed2015-07-22 12:16:45 +1000134 if [[ -z $section || -z $option ]]; then
135 $xtrace
136 return
137 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500138
139 # Add it
Ian Wienandf44a0242015-07-22 10:34:47 +1000140 $sudo sed -i -e "/^\[$section\]/ a\\
Dean Troyerbf2ad702015-03-09 15:16:10 -0500141$option = $value
142" "$file"
143
144 $xtrace
145}
146
147# Remove an option from an INI file
Ian Wienandf44a0242015-07-22 10:34:47 +1000148# inidelete [-sudo] config-file section option
Dean Troyerbf2ad702015-03-09 15:16:10 -0500149function inidelete {
Ian Wienand433a9b12015-10-07 13:29:31 +1100150 local xtrace
151 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -0500152 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +1000153 local sudo=""
154 if [ $1 == "-sudo" ]; then
155 sudo="sudo "
156 shift
157 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500158 local file=$1
159 local section=$2
160 local option=$3
161
Ian Wienand92884ed2015-07-22 12:16:45 +1000162 if [[ -z $section || -z $option ]]; then
163 $xtrace
164 return
165 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500166
167 # Remove old values
Ian Wienandf44a0242015-07-22 10:34:47 +1000168 $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
Dean Troyerbf2ad702015-03-09 15:16:10 -0500169
170 $xtrace
171}
172
173# Set an option in an INI file
Ian Wienandf44a0242015-07-22 10:34:47 +1000174# iniset [-sudo] config-file section option value
Ian Wienandcede7872015-07-22 13:36:12 +1000175# - if the file does not exist, it is created
Dean Troyerbf2ad702015-03-09 15:16:10 -0500176function iniset {
Ian Wienand433a9b12015-10-07 13:29:31 +1100177 local xtrace
178 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -0500179 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +1000180 local sudo=""
Yi Wang698796f2018-12-14 10:35:26 +0800181 local sudo_option=""
Ian Wienandf44a0242015-07-22 10:34:47 +1000182 if [ $1 == "-sudo" ]; then
183 sudo="sudo "
Yi Wang698796f2018-12-14 10:35:26 +0800184 sudo_option="-sudo "
Ian Wienandf44a0242015-07-22 10:34:47 +1000185 shift
186 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500187 local file=$1
188 local section=$2
189 local option=$3
190 local value=$4
191
Nobuhiro MIKId266c872022-08-08 16:45:31 +0900192 # Escape the ampersand character (&)
193 value=$(echo $value | sed -e 's/&/\\&/g')
194
Ian Wienand92884ed2015-07-22 12:16:45 +1000195 if [[ -z $section || -z $option ]]; then
196 $xtrace
197 return
198 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500199
Yi Wang698796f2018-12-14 10:35:26 +0800200 if ! $sudo grep -q "^\[$section\]" "$file" 2>/dev/null; then
Dean Troyerbf2ad702015-03-09 15:16:10 -0500201 # Add section at the end
Ian Wienandf44a0242015-07-22 10:34:47 +1000202 echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
Dean Troyerbf2ad702015-03-09 15:16:10 -0500203 fi
Yi Wang698796f2018-12-14 10:35:26 +0800204 if ! ini_has_option $sudo_option "$file" "$section" "$option"; then
Dean Troyerbf2ad702015-03-09 15:16:10 -0500205 # Add it
Ian Wienandf44a0242015-07-22 10:34:47 +1000206 $sudo sed -i -e "/^\[$section\]/ a\\
Dean Troyerbf2ad702015-03-09 15:16:10 -0500207$option = $value
208" "$file"
209 else
Ian Wienandada886d2015-10-07 14:06:26 +1100210 local sep
211 sep=$(echo -ne "\x01")
Dean Troyerbf2ad702015-03-09 15:16:10 -0500212 # Replace it
Luigi Toscanoc7c67652018-06-04 10:59:57 +0200213 $sudo sed -i -e '/^\['${section}'\]/,/^\[.*\]/ s'${sep}'^\('"${option}"'[ \t]*=[ \t]*\).*$'${sep}'\1'"${value}"${sep} "$file"
Dean Troyerbf2ad702015-03-09 15:16:10 -0500214 fi
215 $xtrace
216}
217
218# Set a multiple line option in an INI file
Atsushi SAKAI5509ed52015-11-30 20:20:21 +0900219# iniset_multiline [-sudo] config-file section option value1 value2 value3 ...
Dean Troyerbf2ad702015-03-09 15:16:10 -0500220function iniset_multiline {
Ian Wienand433a9b12015-10-07 13:29:31 +1100221 local xtrace
222 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -0500223 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +1000224 local sudo=""
225 if [ $1 == "-sudo" ]; then
226 sudo="sudo "
227 shift
228 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500229 local file=$1
230 local section=$2
231 local option=$3
232
233 shift 3
234 local values
235 for v in $@; do
236 # The later sed command inserts each new value in the line next to
237 # the section identifier, which causes the values to be inserted in
238 # the reverse order. Do a reverse here to keep the original order.
239 values="$v ${values}"
240 done
Yi Wang698796f2018-12-14 10:35:26 +0800241 if ! $sudo grep -q "^\[$section\]" "$file"; then
Dean Troyerbf2ad702015-03-09 15:16:10 -0500242 # Add section at the end
Ian Wienandf44a0242015-07-22 10:34:47 +1000243 echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
Dean Troyerbf2ad702015-03-09 15:16:10 -0500244 else
245 # Remove old values
Ian Wienandf44a0242015-07-22 10:34:47 +1000246 $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
Dean Troyerbf2ad702015-03-09 15:16:10 -0500247 fi
248 # Add new ones
249 for v in $values; do
Ian Wienandf44a0242015-07-22 10:34:47 +1000250 $sudo sed -i -e "/^\[$section\]/ a\\
Dean Troyerbf2ad702015-03-09 15:16:10 -0500251$option = $v
252" "$file"
253 done
254 $xtrace
255}
256
257# Uncomment an option in an INI file
258# iniuncomment config-file section option
259function iniuncomment {
Ian Wienand433a9b12015-10-07 13:29:31 +1100260 local xtrace
261 xtrace=$(set +o | grep xtrace)
Dean Troyerbf2ad702015-03-09 15:16:10 -0500262 set +o xtrace
Ian Wienandf44a0242015-07-22 10:34:47 +1000263 local sudo=""
264 if [ $1 == "-sudo" ]; then
265 sudo="sudo "
266 shift
267 fi
Dean Troyerbf2ad702015-03-09 15:16:10 -0500268 local file=$1
269 local section=$2
270 local option=$3
Ian Wienandf44a0242015-07-22 10:34:47 +1000271 $sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|[^ \t]*#[ \t]*\($option[ \t]*=.*$\)|\1|" "$file"
Dean Troyerbf2ad702015-03-09 15:16:10 -0500272 $xtrace
273}
274
vsaienko135bd482015-12-11 11:03:52 +0200275# Get list of sections from an INI file
276# iniget_sections config-file
277function iniget_sections {
278 local xtrace
279 xtrace=$(set +o | grep xtrace)
280 set +o xtrace
281 local file=$1
282
283 echo $(sed -ne "s/^\[\(.*\)\]/\1/p" "$file")
284 $xtrace
285}
286
Sean Daguebb357152016-06-07 11:20:55 -0400287# Set a localrc var
288function localrc_set {
289 local file=$1
290 local group="local"
291 local conf="localrc"
292 local section=""
293 local option=$2
294 local value=$3
295 localconf_set "$file" "$group" "$conf" "$section" "$option" "$value"
296}
297
298# Check if local.conf has section.
299function localconf_has_section {
300 local file=$1
301 local group=$2
302 local conf=$3
303 local section=$4
304 local sep
305 sep=$(echo -ne "\x01")
306 local line
307 line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
308 /\[${section}\]/p
309 }" "$file")
310 [ -n "$line" ]
311}
312
313# Check if local.conf has option.
314function localconf_has_option {
315 local file=$1
316 local group=$2
317 local conf=$3
318 local section=$4
319 local option=$5
320 local sep
321 sep=$(echo -ne "\x01")
322 local line
323 if [[ -z "$section" ]]; then
324 line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
325 /${option}[ \t]*=.*$/p
326 }" "$file")
327 else
328 line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
329 /\[${section}\]/,/\[\[.*\]\]\|\[.*\]/{
330 /${option}[ \t]*=.*$/p}
331 }" "$file")
332 fi
333 [ -n "$line" ]
334}
335
336# Update option in local.conf.
337function localconf_update_option {
338 local sudo=$1
339 local file=$2
340 local group=$3
341 local conf=$4
342 local section=$5
343 local option=$6
344 local value=$7
345 local sep
346 sep=$(echo -ne "\x01")
347 if [[ -z "$section" ]]; then
348 $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
349 s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
350 }" "$file"
351 else
352 $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
353 /\[${section}\]/,/\[\[.*\]\]\|\[.*\]/s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
354 }" "$file"
355 fi
356}
357
358# Add option in local.conf.
359function localconf_add_option {
360 local sudo=$1
361 local file=$2
362 local group=$3
363 local conf=$4
364 local section=$5
365 local option=$6
366 local value=$7
367 local sep
368 sep=$(echo -ne "\x01")
369 if [[ -z "$section" ]]; then
370 $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} a $option=$value" "$file"
371 else
372 $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
373 /\[${section}\]/ a $option=$value
374 }" "$file"
375 fi
376}
377
378# Add section and option in local.conf.
379function localconf_add_section_and_option {
380 local sudo=$1
381 local file=$2
382 local group=$3
383 local conf=$4
384 local section=$5
385 local option=$6
386 local value=$7
387 local sep
388 sep=$(echo -ne "\x01")
389 $sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} {
390 a [$section]
391 a $option=$value
392 }" "$file"
393}
394
395# Set an option in a local.conf file.
396# localconf_set [-sudo] config-file group conf-name section option value
397# - if the file does not exist, it is created
398function localconf_set {
399 local xtrace
400 xtrace=$(set +o | grep xtrace)
401 set +o xtrace
402 local sep
403 sep=$(echo -ne "\x01")
404 local sudo=""
405 if [ $1 == "-sudo" ]; then
406 sudo="sudo "
407 shift
408 fi
409 local file=$1
410 local group=$2
411 local conf=$3
412 local section=$4
413 local option=$5
414 local value=$6
415
416 if [[ -z $group || -z $conf || -z $option || -z $value ]]; then
417 $xtrace
418 return
419 fi
420
421 if ! grep -q "^\[\[${group}|${conf}\]\]" "$file" 2>/dev/null; then
422 # Add meta section at the end if it does not exist
423 echo -e "\n[[${group}|${conf}]]" | $sudo tee --append "$file" > /dev/null
424 # Add section at the end
425 if [[ -n "$section" ]]; then
426 echo -e "[$section]" | $sudo tee --append "$file" > /dev/null
427 fi
428 # Add option at the end
429 echo -e "$option=$value" | $sudo tee --append "$file" > /dev/null
430 elif [[ -z "$section" ]]; then
431 if ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
432 # Add option
433 localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
434 else
435 # Replace it
436 localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
437 fi
438 elif ! localconf_has_section "$file" "$group" "$conf" "$section"; then
439 # Add section and option in specified meta section
440 localconf_add_section_and_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
441 elif ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
442 # Add option
443 localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
444 else
445 # Replace it
446 localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
447 fi
448 $xtrace
449}
450
Dean Troyerbf2ad702015-03-09 15:16:10 -0500451# Restore xtrace
452$INC_CONF_TRACE
453
454# Local variables:
455# mode: shell-script
456# End: