allow packages to optionally append config file contents in the environment by settin...
[openwrt.git] / package / uci / files / uci-sh / lib / config / uci.awk
1 # Configuration update functions - AWK API
2 #
3 # Copyright (C) 2006 by Fokus Fraunhofer <carsten.tittel@fokus.fraunhofer.de>
4 # Copyright (C) 2006 by Felix Fietkau <nbd@openwrt.org>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 # parameters: 1
21 function config_load(package, var) {
22         while (("/bin/ash -c '. /etc/functions.sh; unset NO_EXPORT; config_load \""package"\"; env | grep \"^CONFIG_\"'" | getline) == 1) {
23                 sub("^CONFIG_", "")
24                 if (match($0, "=") == 0) {
25                         if (var != "") CONFIG[var] = CONFIG[var] "\n" $0
26                         next
27                 }
28                 var=substr($0, 1, RSTART-1)
29                 CONFIG[var] = substr($0, RSTART+1, length($0) - RSTART)
30         }
31 }
32
33 # parameters: 2
34 function config_get(package, option) {
35         return CONFIG[package "_" option]
36 }
37
38 # parameters: 3
39 function config_get_bool(package, option, default, var) {
40         var = config_get(package, option);
41         if ((var == "enabled") || (var == "true") || (var == "1") || (var == "on")) return 1
42         if ((var == "disabled") || (var == "false") || (var == "0") || (var == "off")) return 1
43         return (var && var != "0" ? 1 : 0)
44 }
45
46
47 function read_file(filename,  result) {
48         while ((getline <filename) == 1) {
49                 result = result $0 "\n"
50         }
51         gsub(/\n*$/, "", result)
52         return result
53 }
54
55 function uci_cmd2option(str,  tmp) {
56         if (match(str,"=")!=0) {
57                 res = "\toption " substr(str,1,RSTART-1) "\t'" substr(str,RSTART+1) "'"
58         } else {
59                 res= ""
60         }
61         return res
62 }
63
64 function uci_cmd2config(atype,  aname) {
65         return "config \"" atype "\" \"" aname "\""
66 }
67
68 function uci_update_config(cfg, update,  \
69   lines, line, l, n, i, i2, section, scnt, remove, tmp, aidx, rest) {
70         scnt = 1
71         linecnt=split(cfg "\n", lines, "\n")
72
73         cfg = ""
74         for (n = 1; n < linecnt; n++) {
75                 # stupid parser for quoted arguments (e.g. for the type string).
76                 # not to be used to gather variable values (backslash escaping doesn't work)
77                 line = lines[n]
78                 gsub(/^[ \t]*/, "", line)
79                 gsub(/#.*$/, "", line)
80                 i2 = 1
81                 delete l
82                 rest = line
83                 while (length(rest)) {
84                         if (match(rest, /[ \t\"]+/)) {
85                                 if (RSTART>1) {
86                                         l[i2] = substr(rest,1,RSTART-1)
87                                         i2++
88                                 }
89                                 aidx=index(rest,"\"")
90                                 if (aidx>=RSTART && aidx<=RSTART+RLENGTH) {
91                                         rest=substr(rest,aidx+1)
92                                         # find the end of the string
93                                         match(rest,/\"/)
94                                         l[i2]=substr(rest,1,RSTART-1)
95                                         i2++
96                                 }
97                                 rest=substr(rest,RSTART+RLENGTH)
98                         } else {
99                                 l[i2] = rest
100                                 i2++
101                                 rest = ""
102                         }
103                 }
104                 line = lines[n]
105
106                 # when a command wants to set a config value for the current
107                 # section and a blank line is encountered before an option with
108                 # the same name, insert it here to maintain some coherency between
109                 # manually and automatically created option lines
110                 # if an option with the same name appears after this point, simply
111                 # ignore it, because it is already set.
112                 if ((section != "") && (l[1] != "option")) {
113                         if (line ~ /^[ \t]*$/) {
114                                 if (update ~ "^" section "\\.") {
115                                         gsub("^" section ".", "", update)
116                                         cfg = cfg uci_cmd2option(update) "\n"
117                                         gsub(/=.*$/, "", update)
118                                         update = "-" section "." update
119                                 }
120                         }
121                 }
122
123                 if (l[1] == "config") {
124                         # look for all unset values
125                         if (section != "") {
126                                 flag=0
127                                 if (update ~ "^" section "\\.") {
128                                         flag=1
129                                         gsub("^" section ".", "", update)
130                                         cfg = cfg uci_cmd2option(update) "\n"
131
132                                         update = "-" section "." update
133                                 }
134                                 if (flag!=0) cfg = cfg "\n"
135                         }
136
137                         remove = ""
138                         section = l[3]
139                         if (!length(section)) {
140                                 section = "cfg" scnt
141                         }
142                         scnt++
143                         if (update == "-" section) {
144                                 remove = "section"
145                                 update = ""
146                         } else if (update ~ "^@" section "=") {
147                                 update = ""
148                         } else if (update ~ "^&" section "=") {
149                                 gsub("^&" section "=", "", update)
150                                 line = uci_cmd2config(l[2],update)
151                                 update = ""
152                         }
153                 }
154                 if (remove == "option") remove = ""
155                 if (l[1] == "option") {
156                         if (update ~ "^-" section "\\." l[2] "$") remove = "option"
157                         # if a supplied config value already exists, replace the whole line
158                         if (match(update, "^" section "." l[2] "=")) {
159                                 gsub("^" section ".", "", update)
160                                 line = uci_cmd2option(update)
161                                 update = ""
162                         }
163                 }
164                 if (remove == "") cfg = cfg line "\n"
165         }
166
167         # any new options for the last section??
168         if (section != "") {
169                 if (update ~ "^" section "\\.") {
170                         gsub("^" section ".", "", update)
171                         cfg = cfg uci_cmd2option(update) "\n"
172
173                         update = "-" section "." update
174                 }
175         }
176
177         if (update ~ "^@") {
178                 # new section
179                 section = stype = substr(update,2)
180                 gsub(/=.*$/,"",section)
181                 gsub(/^.*=/,"",stype)
182                 cfg = cfg "\nconfig \"" stype "\" \"" section "\"\n"
183         }
184
185         return cfg
186 }