Opennet Firmware
 Alle Dateien Funktionen Variablen Gruppen Seiten
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 
7 uci_is_true() {
8  uci_is_false "$1" && trap "" $GUARD_TRAPS && return 1
9  return 0
10 }
11 
12 
13 uci_is_false() {
14  local token=$1
15  [ "$token" = "0" -o "$token" = "no" -o "$token" = "n" -o "$token" = "off" -o "$token" = "false" ] && return 0
16  trap "" $GUARD_TRAPS && return 1
17 }
18 
19 
20 # "uci -q get ..." endet mit einem Fehlercode falls das Objekt nicht existiert
21 # Dies erschwert bei strikter Fehlerpruefung (set -e) die Abfrage von uci-Werten.
22 # Die Funktion "uci_get" liefert bei fehlenden Objekten einen leeren String zurueck
23 # oder den gegebenen Standardwert zurueck.
24 # Der Exitcode signalisiert immer Erfolg.
25 # Syntax:
26 # uci_get firewall.zone_free.masq 1
27 # Der abschließende Standardwert (zweiter Parameter) ist optional.
28 uci_get() {
29  local key=$1
30  local default=${2:-}
31  if uci -q get "$key"; then
32  return 0
33  else
34  [ -n "$default" ] && echo "$default"
35  return 0
36  fi
37 }
38 
39 
40 ## @fn uci_add_list()
41 ## @brief Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
42 ## @param uci_path Der UCI-Pfad des Listenelements.
43 ## @param new_item Der neue Wert, der zur Liste hinzugefügt werden soll.
44 ## @details Die Funktion ist vergleichbar mit "uci add_list". Es werden jedoch keine doppelten Einträge erzeugt.
45 ## Somit entfällt die Prüfung auf Vorhandensein des Eintrags.
46 uci_add_list() {
47  local uci_path="$1"
48  local new_item="$2"
49  # ist der Eintrag bereits vorhanden?
50  local index=$(uci_get_list_index "$uci_path" "$new_item")
51  # schon vorhanden? Fertig ...
52  [ -n "$index" ] && return 0
53  uci add_list "$uci_path=$new_item"
54 }
55 
56 
57 ## @fn uci_get_list()
58 ## @brief Liefere alle einzelenen Elemente einer UCI-Liste zurück.
59 ## @param uci_path Der UCI-Pfad eines Elements.
60 ## @returns Die Einträge sind zeilenweise voneinander getrennt.
61 uci_get_list() {
62  local uci_path="$1"
63  # falls es den Schlüssel nicht gibt, liefert "uci show" eine Fehlermeldung und Müll - das wollen wir abfangen
64  [ -z "$(uci_get "$uci_path")" ] && return 0
65  # ansonsten: via "uci show" mit speziellem Trenner abfragen und zeilenweise separieren
66  uci show -d "_=_=_=_=_" "$uci_path" | cut -f 2- -d = | sed 's/_=_=_=_=_/\n/g'
67 }
68 
69 
70 ## @fn uci_get_list_index()
71 ## @brief Ermittle die ID eines UCI-Listenelements.
72 ## @param uci_path Der UCI-Pfad der Liste.
73 ## @param value Der Inhalt des zu suchenden Elements.
74 ## @returns Die ID des Listenelements (beginnend bei Null) wird zurückgeliefert.
75 ## @details Falls das Element nicht gefunden wird, ist das Ergebnis leer.
77  local uci_path="$1"
78  local value="$2"
79  local current
80  local index=0
81  uci_get_list "$uci_path" | while read current; do
82  [ "$current" = "$value" ] && echo "$index" && return 0
83  : $((index++))
84  done
85  return 0
86 }
87 
88 
89 ## @fn uci_delete_list()
90 ## @brief Lösche ein Element einer UCI-Liste
91 ## @param uci_path Der UCI-Pfad der Liste.
92 ## @param value Der Inhalt des zu löschenden Elements. Es findet ein Vergleich auf Identität (kein Muster) statt.
93 ## @details Falls das Element nicht existiert, endet die Funktion stillschweigend ohne Fehlermeldung.
95  local uci_path="$1"
96  local value="$2"
97  local index=$(uci_get_list_index "$uci_path" "$value")
98  [ -n "$index" ] && uci_delete "${uci_path}=${index}"
99  return 0
100 }
101 
102 
103 ## @fn uci_delete()
104 ## @brief Lösche ein UCI-Element.
105 ## @param uci_path Der UCI-Pfad des Elements.
106 ## @details Keine Fehlermeldung, falls das Element nicht existiert.
107 uci_delete() {
108  local uci_path="$1"
109  uci -q delete "$uci_path" || true
110 }
111 
112 
113 # Finde eine uci-Sektion mit gewuenschten Eigenschaften.
114 # Dies ist hilfreich beim Auffinden von olsrd.@LoadPlugin, sowie firewall-Zonen und aehnlichem.
115 # Parameter config: Name der uci-config-Datei
116 # Parameter stype: Typ der Sektion (z.B. "zone" oder "LoadPlugin")
117 # Parameter Bedingugen:
118 find_all_uci_sections() {
119  _find_uci_sections 0 "$@"
120 }
121 
122 
123 # Ermittle den ersten Treffer einer uci-Sektionssuche (siehe find_all_uci_sections)
124 find_first_uci_section() {
125  _find_uci_sections 1 "$@"
126 }
127 
128 
129 # Aus Performance-Gruenden brechen wir frueh ab, falls die gewuenschte Anzahl an Ergebnissen erreicht ist.
130 # Die meisten Anfragen suchen nur einen Treffen ("find_first_uci_section") - daher koennen wir hier viel Zeit sparen.
131 _find_uci_sections() {
132  local max_num=$1
133  local config=$2
134  local stype=$3
135  shift 3
136  local counter=0
137  local section
138  local condition
139  # dieser Cache beschleunigt den Vorgang wesentlich
140  local uci_cache_file=$(mktemp)
141  uci -X show "$config" >"$uci_cache_file"
142  grep "^$config\.[^.]\+=$stype$" "$uci_cache_file" | cut -f 1 -d = | cut -f 2 -d . | while read section; do
143  for condition in "$@"; do
144  # diese Sektion ueberspringen, falls eine der Bedingungen fehlschlaegt
145  grep -q "^$config\.$section\.$condition$" "$uci_cache_file" || continue 2
146  done
147  # alle Bedingungen trafen zu
148  echo "$config.$section"
149  : $((counter++))
150  [ "$max_num" = 0 ] && continue
151  [ "$counter" -ge "$max_num" ] && break
152  done | sort
153  rm -f "$uci_cache_file"
154  return 0
155 }
156 
157 
158 # Erzeuge die notwendigen on-core-Einstellungen fuer uci, falls sie noch nicht existieren.
159 # Jede Funktion, die im on-core-Namensraum Einstellungen schreiben moechte, moege diese
160 # Funktion zuvor aufrufen.
161 prepare_on_uci_settings() {
162  local section
163  # on-core-Konfiguration erzeugen, falls noetig
164  [ -e /etc/config/on-core ] || touch /etc/config/on-core
165  for section in settings; do
166  uci show | grep -q "^on-core\.${section}\." || uci set "on-core.${section}=$section"
167  done
168 }
169 
170 # Ende der Doku-Gruppe
171 ## @}