* new project: ff-luci - Freifunk Lua Configuration Interface
[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.exec(ucicmd .. " 2>&1 " .. cmd, true)
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