Added module for system abstraction
[project/luci.git] / src / ffluci / model / uci.lua
1 --[[
2 FFLuCI - UCI wrapper library
3
4 Description:
5 Wrapper for the /sbin/uci application, syntax of implemented functions
6 is comparable to the syntax of the uci application
7
8 Any return value of false or nil can be interpreted as an error
9
10 FileId:
11 $Id$
12
13 License:
14 Copyright 2008 Steven Barth <steven@midlink.org>
15
16 Licensed under the Apache License, Version 2.0 (the "License");
17 you may not use this file except in compliance with the License.
18 You may obtain a copy of the License at
19
20 http://www.apache.org/licenses/LICENSE-2.0
21
22 Unless required by applicable law or agreed to in writing, software
23 distributed under the License is distributed on an "AS IS" BASIS,
24 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 See the License for the specific language governing permissions and
26 limitations under the License.
27
28 ]]--
29 module("ffluci.model.uci", package.seeall)
30 require("ffluci.util")
31
32 ucicmd = "uci"
33
34 -- Wrapper for "uci add"
35 function add(config, section_type)
36 return _uci("add " .. _path(config) .. " " .. _path(section_type))
37 end
38
39
40 -- Wrapper for "uci changes"
41 function changes(config)
42 return _uci3("changes " .. _path(config))
43 end
44
45
46 -- Wrapper for "uci commit"
47 function commit(config)
48 return _uci2("commit " .. _path(config))
49 end
50
51
52 -- Wrapper for "uci get"
53 function get(config, section, option)
54 return _uci("get " .. _path(config, section, option))
55 end
56
57
58 -- Wrapper for "uci revert"
59 function revert(config)
60 return _uci2("revert " .. _path(config))
61 end
62
63
64 -- Wrapper for "uci show"
65 function show(config)
66 return _uci3("show " .. _path(config))
67 end
68
69
70 -- Wrapper for "uci set"
71 function set(config, section, option, value)
72 return _uci2("set " .. _path(config, section, option, value))
73 end
74
75
76 -- Internal functions --
77
78 function _uci(cmd)
79 local res = ffluci.util.exec(ucicmd .. " 2>/dev/null " .. cmd)
80
81 if res:len() == 0 then
82 return nil
83 else
84 return res:sub(1, res:len()-1)
85 end
86 end
87
88 function _uci2(cmd)
89 local res = ffluci.util.exec(ucicmd .. " 2>&1 " .. cmd)
90
91 if res:len() > 0 then
92 return false, res
93 else
94 return true
95 end
96 end
97
98 function _uci3(cmd)
99 local res = ffluci.util.execl(ucicmd .. " 2>&1 " .. cmd)
100 if res[1]:sub(1, ucicmd:len() + 1) == ucicmd .. ":" then
101 return nil, res[1]
102 end
103
104 table = {}
105
106 for k,line in pairs(res) do
107 c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$")
108 if c then
109 table[c] = table[c] or {}
110 table[c][s] = {}
111 table[c][s][".type"] = t
112 end
113
114 c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$")
115 if c then
116 table[c][s][o] = v
117 end
118 end
119
120 return table
121 end
122
123 -- Build path (config.section.option=value) and prevent command injection
124 function _path(...)
125 local result = ""
126
127 -- Not using ipairs because it is not reliable in case of nil arguments
128 arg.n = nil
129 for k,v in pairs(arg) do
130 if k == 1 then
131 result = "'" .. v:gsub("['.]", "") .. "'"
132 elseif k < 4 then
133 result = result .. ".'" .. v:gsub("['.]", "") .. "'"
134 elseif k == 4 then
135 result = result .. "='" .. v:gsub("'", "") .. "'"
136 end
137 end
138 return result
139 end