Opennet Firmware
uci.sh
gehe zur Dokumentation dieser Datei
1## @defgroup uci UCI
2## @brief Hilfreiche Funktionen zum lesenden und schreibenden Zugriff auf die UCI-basierte Konfiguration.
3# Beginn der Doku-Gruppe
4## @{
5
6
7uci_is_true() {
8 uci_is_false "$1" && trap "" EXIT && return 1
9 return 0
11
12
13uci_is_false() {
14 local token="$1"
15 # synchron halten mit "uci_to_bool" (lua-Module)
16 if [ "$token" = "0" ] || [ "$token" = "no" ] || [ "$token" = "n" ] \
17 || [ "$token" = "off" ] || [ "$token" = "false" ]; then
18 return 0
19 else
20 trap "" EXIT && return 1
21 fi
23
24
25# "uci -q get ..." endet mit einem Fehlercode falls das Objekt nicht existiert
26# Dies erschwert bei strikter Fehlerpruefung (set -e) die Abfrage von uci-Werten.
27# Die Funktion "uci_get" liefert bei fehlenden Objekten einen leeren String zurueck
28# oder den gegebenen Standardwert zurueck.
29# Der Exitcode signalisiert immer Erfolg.
30# Syntax:
31# uci_get firewall.zone_free.masq 1
32# Der abschließende Standardwert (zweiter Parameter) ist optional.
33uci_get() {
34 trap 'error_trap uci_get "$*"' EXIT
35 local key="$1"
36 local default="${2:-}"
37 if uci -q get "$key"; then
38 return 0
39 else
40 [ -n "$default" ] && echo "$default"
41 return 0
42 fi
43}
44
45
46## @fn uci_add_list()
47## @brief Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
48## @param uci_path Der UCI-Pfad des Listenelements.
49## @param new_item Der neue Wert, der zur Liste hinzugefügt werden soll.
50## @details Die Funktion ist vergleichbar mit "uci add_list". Es werden jedoch keine doppelten Einträge erzeugt.
51## Somit entfällt die Prüfung auf Vorhandensein des Eintrags.
53 trap 'error_trap uci_add_list "$*"' EXIT
54 local uci_path="$1"
55 local new_item="$2"
56 local index
57 # ist der Eintrag bereits vorhanden?
58 uci_is_in_list "$uci_path" "$new_item" && return 0
59 uci add_list "$uci_path=$new_item"
60}
61
62
63## @fn uci_get_list()
64## @brief Liefere alle einzelnen Elemente einer UCI-Liste zurück.
65## @param uci_path Der UCI-Pfad eines Elements.
66## @returns Die Einträge sind zeilenweise voneinander getrennt.
68 trap 'error_trap uci_get_list "$*"' EXIT
69 local uci_path="$1"
70 # falls es den Schlüssel nicht gibt, liefert "uci show" eine Fehlermeldung und Müll - das wollen wir abfangen
71 [ -z "$(uci_get "$uci_path")" ] && return 0
72 # ansonsten: via "uci show" mit speziellem Trenner abfragen und zeilenweise separieren
73 uci -q -d "_=_=_=_=_" show "$uci_path" | cut -f 2- -d = | sed 's/_=_=_=_=_/\n/g' | sed "s/^'"'\‍(.*\‍)'"'"'$/\1/'
74}
75
76
77## @fn uci_get_list_index()
78## @brief Ermittle die ID eines UCI-Listenelements.
79## @param uci_path Der UCI-Pfad der Liste.
80## @param value Der Inhalt des zu suchenden Elements.
81## @returns Die ID des Listenelements (beginnend bei Null) wird zurückgeliefert.
82## @details Falls das Element nicht gefunden wird, ist das Ergebnis leer.
84 trap 'error_trap uci_get_list_index "$*"' EXIT
85 local uci_path="$1"
86 local value="$2"
87 local current
88 local index=0
89 for current in $(uci_get_list "$uci_path"); do
90 [ "$current" = "$value" ] && echo "$index" && break
91 index=$((index + 1))
92 done
93}
94
95
96## @fn uci_is_in_list()
97## @param uci_path Der UCI-Pfad der Liste.
98## @param item Das zu suchende Element.
99## @brief Prüfe ob ein Element in einer Liste vorkommt.
101 trap 'error_trap uci_is_in_list "$*"' EXIT
102 local uci_path="$1"
103 local value="$2"
104 [ -n "$(uci_get_list_index "$uci_path" "$value")" ] && return 0
105 trap "" EXIT && return 1
106}
107
108
109## @fn uci_delete_list()
110## @brief Lösche ein Element einer UCI-Liste
111## @param uci_path Der UCI-Pfad der Liste.
112## @param value Der Inhalt des zu löschenden Elements. Es findet ein Vergleich auf Identität (kein Muster) statt.
113## @details Falls das Element nicht existiert, endet die Funktion stillschweigend ohne Fehlermeldung.
115 trap 'error_trap uci_delete_list "$*"' EXIT
116 local uci_path="$1"
117 local value="$2"
118 local index
119 index=$(uci_get_list_index "$uci_path" "$value")
120 [ -n "$index" ] && uci_delete "${uci_path}=${index}"
121 return 0
122}
123
124
125## @fn uci_replace_list()
126## @brief Replace the items in a list. Wanted items are expected via stdin (one per line).
127## @param uci_path The path of the UCI list.
128## @details This function is idempotent. Thus it takes care to avoid unnecessary changes (e.g. an
129## existing list being replaced with all of its current members). This works around UCI's
130## behaviour of not detecting (and discarding) no-change-operations. The list is removed if no
131## items were supplied. Some processes may rely on the avoidance of unnecessary changes.
133 local uci_path="$1"
134 local current_list_items
135 local wanted_list_items
136 current_list_items=$(uci_get_list "$uci_path" | sort)
137 wanted_list_items=$(sort)
138 if [ "$current_list_items" != "$wanted_list_items" ]; then
139 uci_delete "$uci_path"
140 echo "$wanted_list_items" | while read -r item; do
141 uci_add_list "$uci_path" "$item"
142 done
143 fi
144}
145
146
147## @fn uci_delete()
148## @brief Lösche ein UCI-Element.
149## @param uci_path Der UCI-Pfad des Elements.
150## @details Keine Fehlermeldung, falls das Element nicht existiert.
151uci_delete() {
152 local uci_path="$1"
153 uci -q delete "$uci_path" || true
154}
155
156
157# Finde eine uci-Sektion mit gewuenschten Eigenschaften.
158# Dies ist hilfreich beim Auffinden von olsrd.@LoadPlugin, sowie firewall-Zonen und aehnlichem.
159# Parameter config: Name der uci-config-Datei
160# Parameter stype: Typ der Sektion (z.B. "zone" oder "LoadPlugin")
161# Parameter Bedingugen:
162find_all_uci_sections() {
163 _find_uci_sections 0 "$@"
164}
165
166
167# Ermittle den ersten Treffer einer uci-Sektionssuche (siehe find_all_uci_sections)
168find_first_uci_section() {
169 _find_uci_sections 1 "$@"
170}
171
172
173## @fn filter_uci_show_value_quotes()
174## @brief Entferne fuehrende und abschliessende Quotes um die Werte der "uci show"-Ausgabe herum.
175## @details Seit Chaos Calmer liefert 'uci show' die Werte (nach dem "=") mit Single-Quotes zurück.
176## Dies ist schön für die Splittung von Listen, aber nervig für unsere Bedingungsprüfung.
177## Wir entfernen die Quotes daher.
178## @attention Das Ergebnis ist fuer die Verarbeitung von Listen-Elemente unbrauchbar, da diese separiert
179## von Quotes umgeben sind.
181 sed 's/^\‍([^=]\+\‍)='"'"'\‍(.*\‍)'"'"'$/\1=\2/'
182}
183
184
185# Aus Performance-Gruenden brechen wir frueh ab, falls die gewuenschte Anzahl an Ergebnissen erreicht ist.
186# Die meisten Anfragen suchen nur einen Treffer ("find_first_uci_section") - daher koennen wir hier viel Zeit sparen.
187_find_uci_sections() {
188 trap 'error_trap _find_uci_sections "$*"' EXIT
189 local max_num="$1"
190 local config="$2"
191 local stype="$3"
192 shift 3
193 local counter=0
194 local section
195 local condition
196 # Der Cache beschleunigt den Vorgang wesentlich.
197 uci_cache=$(uci -X -q show "$config" | filter_uci_show_value_quotes)
198 for section in $(echo "$uci_cache" | grep "^$config"'\.[^.]\+='"$stype$" | cut -f 1 -d = | cut -f 2 -d .); do
199 for condition in "$@"; do
200 # diese Sektion ueberspringen, falls eine der Bedingungen fehlschlaegt
201 echo "$uci_cache" | grep -q "^$config"'\.'"$section"'\.'"$condition$" || continue 2
202 done
203 # alle Bedingungen trafen zu
204 echo "$config.$section"
205 counter=$((counter + 1))
206 [ "$max_num" != 0 ] && [ "$counter" -ge "$max_num" ] && break
207 true
208 done | sort
209}
210
211
212# Erzeuge die notwendigen on-core-Einstellungen fuer uci, falls sie noch nicht existieren.
213# Jede Funktion, die im on-core-Namensraum Einstellungen schreiben moechte, moege diese
214# Funktion zuvor aufrufen.
215prepare_on_uci_settings() {
216 trap 'error_trap prepare_on_uci_settings "$*"' EXIT
217 local section
218 # on-core-Konfiguration erzeugen, falls noetig
219 [ -e /etc/config/on-core ] || touch /etc/config/on-core
220 # shellcheck disable=SC2043
221 for section in settings; do
222 uci show | grep -q '^on-core\.'"${section}"'\.' || uci set "on-core.${section}=$section"
223 done
224}
225
226
227## @fn create_uci_section_if_missing
228## @brief Prüfe, ob eine definierte UCI-Sektion existiert und lege sie andernfalls an.
229## @returns Sektion wurde angelegt (True) oder war bereits vorhanden (false).
231 trap 'error_trap create_uci_section_if_missing "$*"' EXIT
232 local config="$1"
233 local stype="$2"
234 local key_value
235 local uci_prefix
236 shift 2
237 # liefere "falsch" zurück (Sektion war bereits vorhanden)
238 [ -n "$(find_first_uci_section "$config" "$stype" "$@")" ] && { trap "" EXIT; return 1; }
239 # uci-Sektion fehlt -> anlegen
240 uci_prefix="$config.$(uci add "$config" "$stype")"
241 for key_value in "$@"; do
242 uci set "$uci_prefix.$key_value"
243 done
244 # liefere "wahr" zurück (Sektion wurde angelegt)
245 return 0
246}
247
248# Ende der Doku-Gruppe
249## @}
do echo n $value
Definition: core.sh:85
key
Definition: core.sh:85
shift
Definition: core.sh:85
done
Definition: core.sh:85
while read r key value
Definition: core.sh:85
uci_get_list_index(uci_path, value)
Ermittle die ID eines UCI-Listenelements.
Definition: uci.sh:22
create_uci_section_if_missing()
Prüfe, ob eine definierte UCI-Sektion existiert und lege sie andernfalls an.
Definition: uci.sh:58
uci_is_in_list(uci_path, item)
Prüfe ob ein Element in einer Liste vorkommt.
Definition: uci.sh:27
uci_delete(uci_path)
Lösche ein UCI-Element.
Definition: uci.sh:46
uci_replace_list()
Replace the items in a list. Wanted items are expected via stdin (one per line, uci_path).
Definition: uci.sh:41
filter_uci_show_value_quotes()
Entferne fuehrende und abschliessende Quotes um die Werte der "uci show"-Ausgabe herum.
Definition: uci.sh:54
uci_get_list(uci_path)
Liefere alle einzelnen Elemente einer UCI-Liste zurück.
Definition: uci.sh:15
uci_add_list(uci_path, new_item)
Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
Definition: uci.sh:10
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
Definition: uci.sh:33
set eu on function print_services services log for dir in etc on services d var on services volatile d
Definition: services:13