* Mördercommit ;-)
[project/luci.git] / core / src / model / uci / libuci.lua
1 --[[
2 FFLuCI - UCI libuci wrapper
3
4 Description:
5 Wrapper for the libuci Lua bindings
6
7 FileId:
8 $Id$
9
10 License:
11 Copyright 2008 Steven Barth <steven@midlink.org>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
16
17 http://www.apache.org/licenses/LICENSE-2.0
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 ]]--
26
27 module("ffluci.model.uci.libuci", package.seeall)
28
29 require("uci")
30 require("ffluci.util")
31 require("ffluci.sys")
32
33 -- Session class
34 Session = ffluci.util.class()
35
36 -- Session constructor
37 function Session.__init__(self, savedir)
38 self.ucicmd = savedir and "uci -P " .. savedir or "uci"
39 self.savedir = savedir or ffluci.model.uci.savedir
40 end
41
42 function Session.add(self, config, section_type)
43 return self:_uci("add " .. _path(config) .. " " .. _path(section_type))
44 end
45
46 function Session.changes(self, config)
47 return self:_uci("changes " .. _path(config))
48 end
49
50 function Session.commit(self, config)
51 self:t_load(config)
52 return self:t_commit(config)
53 end
54
55 function Session.del(self, config, section, option)
56 return self:_uci2("del " .. _path(config, section, option))
57 end
58
59 function Session.get(self, config, section, option)
60 self:t_load(config)
61 return self:t_get(config, section, option)
62 end
63
64 function Session.revert(self, config)
65 self:t_load(config)
66 return self:t_revert(config)
67 end
68
69 function Session.sections(self, config)
70 self:t_load(config)
71 return self:t_sections(config)
72 end
73
74 function Session.set(self, config, section, option, value)
75 self:t_load(config)
76 return self:t_set(config, section, option, value) and self:t_save(config)
77 end
78
79 function Session.synchronize(self)
80 return uci.set_savedir(self.savedir)
81 end
82
83
84 -- UCI-Transactions
85
86 function Session.t_load(self, config)
87 return self:synchronize() and uci.load(config)
88 end
89
90 function Session.t_save(self, config)
91 return uci.save(config)
92 end
93
94 function Session.t_add(self, config, type)
95 self:t_save(config)
96 local r = self:add(config, type)
97 self:t_load(config)
98 return r
99 end
100
101 function Session.t_commit(self, config)
102 return uci.commit(config)
103 end
104
105 function Session.t_del(self, config, section, option)
106 self:t_save(config)
107 local r = self:del(config, section, option)
108 self:t_load(config)
109 return r
110 end
111
112 function Session.t_get(self, config, section, option)
113 if option then
114 return uci.get(config, section, option)
115 else
116 return uci.get(config, section)
117 end
118 end
119
120 function Session.t_revert(self, config)
121 return uci.revert(config)
122 end
123
124 function Session.t_sections(self, config)
125 local raw = uci.get_all(config)
126 if not raw then
127 return nil
128 end
129
130 local s = {}
131 local o = {}
132
133 for i, sec in ipairs(raw) do
134 table.insert(o, sec.name)
135
136 s[sec.name] = sec.options
137 s[sec.name][".type"] = sec.type
138 end
139
140 return s, o
141 end
142
143 function Session.t_set(self, config, section, option, value)
144 if option then
145 return uci.set(config.."."..section.."."..option.."="..value)
146 else
147 return uci.set(config.."."..section.."="..value)
148 end
149 end
150
151 -- Internal functions --
152
153
154 function Session._uci(self, cmd)
155 local res = ffluci.sys.exec(self.ucicmd .. " 2>/dev/null " .. cmd)
156
157 if res:len() == 0 then
158 return nil
159 else
160 return res:sub(1, res:len()-1)
161 end
162 end
163
164 function Session._uci2(self, cmd)
165 local res = ffluci.sys.exec(self.ucicmd .. " 2>&1 " .. cmd)
166
167 if res:len() > 0 then
168 return false, res
169 else
170 return true
171 end
172 end
173
174 -- Build path (config.section.option=value) and prevent command injection
175 function _path(...)
176 local result = ""
177
178 -- Not using ipairs because it is not reliable in case of nil arguments
179 arg.n = nil
180 for k,v in pairs(arg) do
181 if v then
182 v = tostring(v)
183 if k == 1 then
184 result = "'" .. v:gsub("['.]", "") .. "'"
185 elseif k < 4 then
186 result = result .. ".'" .. v:gsub("['.]", "") .. "'"
187 elseif k == 4 then
188 result = result .. "='" .. v:gsub("'", "") .. "'"
189 end
190 end
191 end
192 return result
193 end