9a1112500e60dd0dc57d252b8cec4cb335156acc
[project/luci.git] / libs / core / luasrc / model / uci / libuci.lua
1 --[[
2 LuCI - 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("luci.model.uci.libuci", package.seeall)
28
29 require("uci")
30 require("luci.util")
31 require("luci.sys")
32
33 -- Session class
34 Session = luci.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 luci.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 = luci.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 = luci.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