* Rewrote and optimized ffluci.model.uci
authorSteven Barth <steven@midlink.org>
Tue, 6 May 2008 14:28:51 +0000 (14:28 +0000)
committerSteven Barth <steven@midlink.org>
Tue, 6 May 2008 14:28:51 +0000 (14:28 +0000)
* Use optimized UCI code for ffluci.cbi and ffluci.controller.admin.index if possible

contrib/package/ffluci-splash/src/luci-splash.lua
core/src/ffluci/cbi.lua
core/src/ffluci/model/uci.lua
core/src/ffluci/model/uci/libuci.lua
core/src/ffluci/model/uci/wrapper.lua
module/admin-core/src/controller/admin/index.lua
module/admin-core/src/controller/admin/uci.lua

index 1520491..2fa6bdd 100644 (file)
@@ -72,7 +72,7 @@ end
 function remove_lease(mac)
        mac = mac:lower()
 
-       for k, v in pairs(uci:show("luci_splash").luci_splash) do
+       for k, v in pairs(uci:sections("luci_splash")) do
                if v[".type"] == "lease" and v.mac:lower() == mac then
                        remove_rule(mac)
                        uci:del("luci_splash", k)
@@ -97,7 +97,7 @@ end
 function haslease(mac)
        mac = mac:lower()
        
-       for k, v in pairs(uci:show("luci_splash").luci_splash) do
+       for k, v in pairs(uci:sections("luci_splash")) do
                if v[".type"] == "lease" and v.mac and v.mac:lower() == mac then
                        return true
                end
@@ -111,7 +111,7 @@ end
 function iswhitelisted(mac)
        mac = mac:lower()
        
-       for k, v in pairs(uci:show("luci_splash").luci_splash) do
+       for k, v in pairs(uci:sections("luci_splash")) do
                if v[".type"] == "whitelist" and v.mac and v.mac:lower() == mac then
                        return true
                end
@@ -134,14 +134,16 @@ function sync()
        local written = {}
        local time = os.time()
        
+       uci:t_load("luci_splash")
+       
        -- Current leases in state files
-       local leases = uci:show("luci_splash").luci_splash
+       local leases = uci:t_sections("luci_splash")
        
        -- Convert leasetime to seconds
-       local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600
+       local leasetime = tonumber(uci:t_get("luci_splash", "general", "leasetime")) * 3600
        
        -- Clean state file
-       uci:revert("luci_splash")
+       uci:t_revert("luci_splash")
        
        
        -- For all leases
@@ -152,9 +154,9 @@ function sync()
                                remove_rule(v.mac)
                        else
                                -- Rewrite state
-                               local n = uci:add("luci_splash", "lease")
-                               uci:set("luci_splash", n, "mac", v.mac)
-                               uci:set("luci_splash", n, "start", v.start)
+                               local n = uci:t_add("luci_splash", "lease")
+                               uci:t_set("luci_splash", n, "mac", v.mac)
+                               uci:t_set("luci_splash", n, "start", v.start)
                                written[v.mac:lower()] = 1
                        end
                end
@@ -167,6 +169,8 @@ function sync()
                        remove_rule(r)
                end
        end
+       
+       uci:t_save("luci_splash")
 end
 
 main(arg)
\ No newline at end of file
index 99d742b..4d6d25c 100644 (file)
@@ -119,12 +119,19 @@ function Map.__init__(self, config, ...)
        self.config = config
        self.template = "cbi/map"
        self.uci = ffluci.model.uci.Session()
-       self.ucidata = self.uci:sections(self.config)
-       if not self.ucidata then
+       self.ucidata, self.uciorder = self.uci:sections(self.config)
+       if not self.ucidata or not self.uciorder then
                error("Unable to read UCI data: " .. self.config)
        end
 end
 
+-- Use optimized UCI writing
+function Map.parse(self, ...)
+       self.uci:t_load(self.config)
+       Node.parse(self, ...)
+       self.uci:t_save(self.config)
+end
+
 -- Creates a child section
 function Map.section(self, class, ...)
        if instanceof(class, AbstractSection) then
@@ -138,21 +145,20 @@ end
 
 -- UCI add
 function Map.add(self, sectiontype)
-       local name = self.uci:add(self.config, sectiontype)
+       local name = self.uci:t_add(self.config, sectiontype)
        if name then
                self.ucidata[name] = {}
                self.ucidata[name][".type"] = sectiontype
-               self.ucidata[".order"] = self.ucidata[".order"] or {}
-               table.insert(self.ucidata[".order"], name)
+               table.insert(self.uciorder, name)
        end
        return name
 end
 
 -- UCI set
 function Map.set(self, section, option, value)
-       local stat = self.uci:set(self.config, section, option, value)
+       local stat = self.uci:t_set(self.config, section, option, value)
        if stat then
-               local val = self.uci:get(self.config, section, option)
+               local val = self.uci:t_get(self.config, section, option)
                if option then
                        self.ucidata[section][option] = val
                else
@@ -160,8 +166,7 @@ function Map.set(self, section, option, value)
                                self.ucidata[section] = {}
                        end
                        self.ucidata[section][".type"] = val
-                       self.ucidata[".order"] = self.ucidata[".order"] or {}
-                       table.insert(self.ucidata[".order"], section)
+                       table.insert(self.uciorder, section)
                end
        end
        return stat
@@ -169,15 +174,15 @@ end
 
 -- UCI del
 function Map.del(self, section, option)
-       local stat = self.uci:del(self.config, section, option)
+       local stat = self.uci:t_del(self.config, section, option)
        if stat then
                if option then
                        self.ucidata[section][option] = nil
                else
                        self.ucidata[section] = nil
-                       for i, k in ipairs(self.ucidata[".order"]) do
+                       for i, k in ipairs(self.uciorder) do
                                if section == k then
-                                       table.remove(self.ucidata[".order"], i)
+                                       table.remove(self.uciorder, i)
                                end
                        end
                end
@@ -188,7 +193,7 @@ end
 -- UCI get (cached)
 function Map.get(self, section, option)
        if not section then
-               return self.ucidata
+               return self.ucidata, self.uciorder
        elseif option and self.ucidata[section] then
                return self.ucidata[section][option]
        else
@@ -362,19 +367,16 @@ end
 -- Return all matching UCI sections for this TypedSection
 function TypedSection.cfgsections(self)
        local sections = {}
+       local map, order = self.map:get()
        
-       local map = self.map:get()
-       if not map[".order"] then
-               return sections
-       end
-       
-       for i, k in pairs(map[".order"]) do
+       for i, k in ipairs(order) do
                if map[k][".type"] == self.sectiontype then
                        if self:checkscope(k) then
                                table.insert(sections, k)
                        end
                end
        end
+       
        return sections 
 end
 
index 511c974..ca5b232 100644 (file)
@@ -25,6 +25,9 @@ limitations under the License.
 ]]--
 module("ffluci.model.uci", package.seeall)
 
+-- Default savedir
+savedir = "/tmp/.uci"
+
 -- Test whether to load libuci-Wrapper or /sbin/uci-Wrapper
 if pcall(require, "uci") then
        Session = require("ffluci.model.uci.libuci").Session
@@ -53,7 +56,6 @@ function changes(...)
        return default:changes(...)
 end
 
-
 -- Wrapper for "uci commit"
 function commit(...)
        return default:commit(...)
index 8414fad..b160dc1 100644 (file)
@@ -26,24 +26,17 @@ limitations under the License.
 
 module("ffluci.model.uci.libuci", package.seeall)
 
+require("uci")
 require("ffluci.util")
-require("ffluci.fs")
 require("ffluci.sys")
 
--- The OS uci command
-ucicmd = "uci"
-
 -- Session class
 Session = ffluci.util.class()
 
 -- Session constructor
-function Session.__init__(self, path, uci)
-       uci = uci or ucicmd
-       if path then
-               self.ucicmd = uci .. " -P " .. path 
-       else
-               self.ucicmd = uci
-       end
+function Session.__init__(self, savedir)
+       self.ucicmd  = savedir and "uci -P " .. savedir or "uci"
+       self.savedir = savedir or ffluci.model.uci.savedir
 end
 
 function Session.add(self, config, section_type)
@@ -55,7 +48,8 @@ function Session.changes(self, config)
 end
 
 function Session.commit(self, config)
-       return self:_uci2("commit " .. _path(config))
+       self:t_load(config)
+       return self:t_commit(config)
 end
 
 function Session.del(self, config, section, option)
@@ -63,31 +57,96 @@ function Session.del(self, config, section, option)
 end
 
 function Session.get(self, config, section, option)
-       return self:_uci("get " .. _path(config, section, option))
+       self:t_load(config)
+       return self:t_get(config, section, option)
 end
 
 function Session.revert(self, config)
-       return self:_uci2("revert " .. _path(config))
+       self:t_load(config)
+       return self:t_revert(config)
 end
 
-function Session.sections(self, config)        
-       if not config then
-               return nil
-       end
-       
-       local r1, r2 = self:_uci3("show " .. _path(config))
-       if type(r1) == "table" then
-               return r1[config]
+function Session.sections(self, config)
+       self:t_load(config)
+       return self:t_sections(config)
+end
+
+function Session.set(self, config, section, option, value)
+       self:t_load(config)
+       return self:t_set(config, section, option, value) and self:t_save(config)
+end
+
+function Session.synchronize(self)
+       return uci.set_savedir(self.savedir)
+end
+
+
+-- UCI-Transactions
+
+function Session.t_load(self, config)
+       return self:synchronize() and uci.load(config)
+end
+
+function Session.t_save(self, config)
+       return uci.save(config)
+end
+
+function Session.t_add(self, config, type)
+       self:t_save(config)
+       local r = self:add(config, type)
+       self:t_load(config)
+       return r
+end
+
+function Session.t_commit(self, config)
+       return uci.commit(config)
+end
+
+function Session.t_del(self, config, section, option)
+       self:t_save(config)
+       local r = self:del(config, section, option)
+       self:t_load(config)
+       return r
+end
+
+function Session.t_get(self, config, section, option)
+       if option then
+               return uci.get(config, section, option)
        else
-               return nil, r2
+               return uci.get(config, section)
        end
 end
 
-function Session.set(self, config, section, option, value)
-       return self:_uci2("set " .. _path(config, section, option, value))
+function Session.t_revert(self, config)
+       return uci.revert(config)
 end
 
+function Session.t_sections(self, config)
+       local raw = uci.get_all(config)
+       if not raw then
+               return nil
+       end
+               
+       local s = {}
+       local o = {}
+       
+       for i, sec in ipairs(raw) do 
+               table.insert(o, sec.name)
+               
+               s[sec.name] = sec.options
+               s[sec.name][".type"] = sec.type
+       end
+       
+       return s, o
+end
 
+function Session.t_set(self, config, section, option, value)
+       if option then
+               return uci.set(config.."."..section.."."..option.."="..value)
+       else
+               return uci.set(config.."."..section.."="..value)
+       end
+end
 
 -- Internal functions --
 
@@ -112,34 +171,6 @@ function Session._uci2(self, cmd)
        end     
 end
 
-function Session._uci3(self, cmd)
-       local res = ffluci.sys.execl(self.ucicmd .. " 2>&1 " .. cmd)
-       if res[1] and res[1]:sub(1, self.ucicmd:len()+1) == self.ucicmd..":" then
-               return nil, res[1]
-       end
-
-       tbl = {}
-
-       for k,line in pairs(res) do
-               c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$")
-               if c then
-                       tbl[c] = tbl[c] or {}
-                       tbl[c][".order"] = tbl[c][".order"] or {}
-                       
-                       tbl[c][s] = {}
-                       table.insert(tbl[c][".order"], s)
-                       tbl[c][s][".type"] = t
-               end
-       
-               c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$")
-               if c then
-                       tbl[c][s][o] = v
-               end
-       end
-       
-       return tbl
-end
-
 -- Build path (config.section.option=value) and prevent command injection
 function _path(...)
        local result = ""
index 142e719..3aa3b5f 100644 (file)
@@ -30,23 +30,14 @@ limitations under the License.
 module("ffluci.model.uci.wrapper", package.seeall)
 
 require("ffluci.util")
-require("ffluci.fs")
 require("ffluci.sys")
 
--- The OS uci command
-ucicmd = "uci"
-
 -- Session class
 Session = ffluci.util.class()
 
 -- Session constructor
-function Session.__init__(self, path, uci)
-       uci = uci or ucicmd
-       if path then
-               self.ucicmd = uci .. " -P " .. path 
-       else
-               self.ucicmd = uci
-       end
+function Session.__init__(self, savedir)
+       self.ucicmd = savedir and "uci -P " .. savedir or "uci"
 end
 
 function Session.add(self, config, section_type)
@@ -80,7 +71,7 @@ function Session.sections(self, config)
        
        local r1, r2 = self:_uci3("show " .. _path(config))
        if type(r1) == "table" then
-               return r1[config]
+               return r1, r2
        else
                return nil, r2
        end
@@ -90,6 +81,23 @@ function Session.set(self, config, section, option, value)
        return self:_uci2("set " .. _path(config, section, option, value))
 end
 
+function Session.synchronize(self) end
+
+-- Dummy transaction functions
+
+function Session.t_load(self) end
+function Session.t_save(self) end
+
+Session.t_add = Session.add
+Session.t_commit = Session.commit
+Session.t_del = Session.del
+Session.t_get = Session.get
+Session.t_revert = Session.revert
+Session.t_sections = Session.sections
+Session.t_set = Session.set
+
+
+
 
 
 -- Internal functions --
@@ -121,26 +129,24 @@ function Session._uci3(self, cmd)
                return nil, res[1]
        end
 
-       tbl = {}
+       local tbl = {}
+       local ord = {}
 
        for k,line in pairs(res) do
                c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$")
                if c then
-                       tbl[c] = tbl[c] or {}
-                       tbl[c][".order"] = tbl[c][".order"] or {}
-                       
-                       tbl[c][s] = {}
-                       table.insert(tbl[c][".order"], s)
-                       tbl[c][s][".type"] = t
+                       tbl[s] = {}
+                       table.insert(ord, s)
+                       tbl[s][".type"] = t
                end
        
                c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$")
                if c then
-                       tbl[c][s][o] = v
+                       tbl[s][o] = v
                end
        end
        
-       return tbl
+       return tbl, ord
 end
 
 -- Build path (config.section.option=value) and prevent command injection
index 09d5aa1..edca572 100644 (file)
@@ -23,133 +23,149 @@ function configure_freifunk()
        local ip  = ffluci.http.formvalue("ip")
        local uci = ffluci.model.uci.Session()
        
+       -- Load UCI
+       uci:t_load("network")
+       uci:t_load("dhcp")
+       uci:t_load("freifunk")
+       uci:t_load("luci_splash")
+       uci:t_load("olsr")
+       uci:t_load("wireless")
+       
+       
        -- Configure FF-Interface
-       uci:del("network", "ff")
-       uci:del("network", "ffdhcp")
+       uci:t_del("network", "ff")
+       uci:t_del("network", "ffdhcp")
        
-       uci:set("network", "ff", nil, "interface")
-       uci:set("network", "ff", "type", "bridge")
-       uci:set("network", "ff", "proto", "static")
-       uci:set("network", "ff", "ipaddr", ip)
-       uci:set("network", "ff", "netmask", uci:get("freifunk", "community", "mask")) 
-       uci:set("network", "ff", "dns", uci:get("freifunk", "community", "dns")) 
+       uci:t_set("network", "ff", nil, "interface")
+       uci:t_set("network", "ff", "type", "bridge")
+       uci:t_set("network", "ff", "proto", "static")
+       uci:t_set("network", "ff", "ipaddr", ip)
+       uci:t_set("network", "ff", "netmask", uci:t_get("freifunk", "community", "mask")) 
+       uci:t_set("network", "ff", "dns", uci:t_get("freifunk", "community", "dns")) 
        
        -- Enable internal routing
-       uci:set("freifunk", "routing", "internal", "1")
+       uci:t_set("freifunk", "routing", "internal", "1")
        
        -- Enable internet routing
        if ffluci.http.formvalue("shareinet") then
-               uci:set("freifunk", "routing", "internet", "1")
+               uci:t_set("freifunk", "routing", "internet", "1")
        else
-               uci:set("freifunk", "routing", "internet", "0")
+               uci:t_set("freifunk", "routing", "internet", "0")
        end
        
        -- Configure DHCP
        if ffluci.http.formvalue("dhcp") then
-               local dhcpnet = uci:get("freifunk", "community", "dhcp"):match("^([0-9]+)")
+               local dhcpnet = uci:t_get("freifunk", "community", "dhcp"):match("^([0-9]+)")
                local dhcpip  = ip:gsub("^[0-9]+", dhcpnet)
        
-               uci:set("network", "ffdhcp", nil, "interface")
-               uci:set("network", "ffdhcp", "proto", "static")
-               uci:set("network", "ffdhcp", "ifname", "br-ff:dhcp")
-               uci:set("network", "ffdhcp", "ipaddr", dhcpip)
-               uci:set("network", "ffdhcp", "netmask", uci:get("freifunk", "community", "dhcpmask"))
+               uci:t_set("network", "ffdhcp", nil, "interface")
+               uci:t_set("network", "ffdhcp", "proto", "static")
+               uci:t_set("network", "ffdhcp", "ifname", "br-ff:dhcp")
+               uci:t_set("network", "ffdhcp", "ipaddr", dhcpip)
+               uci:t_set("network", "ffdhcp", "netmask", uci:t_get("freifunk", "community", "dhcpmask"))
                
-               local dhcp = uci:sections("dhcp")
+               local dhcp = uci:t_sections("dhcp")
                if dhcp then
                        for k, v in pairs(dhcp) do
                                if v[".type"] == "dhcp" and v.interface == "ffdhcp" then
-                                       uci:del("dhcp", k)
+                                       uci:t_del("dhcp", k)
                                end
                        end             
                        
                        local dhcpbeg = 48 + tonumber(ip:match("[0-9]+$")) * 4
                        
-                       local sk = uci:add("dhcp", "dhcp")
-                       uci:set("dhcp", sk, "interface", "ffdhcp")
-                       uci:set("dhcp", sk, "start", dhcpbeg)
-                       uci:set("dhcp", sk, "limit", (dhcpbeg < 252) and 3 or 2)
-                       uci:set("dhcp", sk, "leasetime", "30m")
+                       local sk = uci:t_add("dhcp", "dhcp")
+                       uci:t_set("dhcp", sk, "interface", "ffdhcp")
+                       uci:t_set("dhcp", sk, "start", dhcpbeg)
+                       uci:t_set("dhcp", sk, "limit", (dhcpbeg < 252) and 3 or 2)
+                       uci:t_set("dhcp", sk, "leasetime", "30m")
                end 
                
-               local splash = uci:sections("luci_splash")
+               local splash = uci:t_sections("luci_splash")
                if splash then
                        for k, v in pairs(splash) do
                                if v[".type"] == "iface" then
-                                       uci:del("luci_splash", k)
+                                       uci:t_del("luci_splash", k)
                                end
                        end             
                        
-                       local sk = uci:add("luci_splash", "iface")
-                       uci:set("luci_splash", sk, "network", "ffdhcp")
+                       local sk = uci:t_add("luci_splash", "iface")
+                       uci:t_set("luci_splash", sk, "network", "ffdhcp")
                end             
        end
        
        -- Configure OLSR
-       if ffluci.http.formvalue("olsr") and uci:sections("olsr") then
-               for k, v in pairs(uci:sections("olsr")) do
+       if ffluci.http.formvalue("olsr") and uci:t_sections("olsr") then
+               for k, v in pairs(uci:t_sections("olsr")) do
                        if v[".type"] == "Interface" or v[".type"] == "LoadPlugin" then
-                               uci:del("olsr", k)
+                               uci:t_del("olsr", k)
                        end
                end
                
                if ffluci.http.formvalue("shareinet") then
-                       uci:set("olsr", "dyn_gw", nil, "LoadPlugin")
-                       uci:set("olsr", "dyn_gw", "Library", "olsrd_dyn_gw.so.0.4")
+                       uci:t_set("olsr", "dyn_gw", nil, "LoadPlugin")
+                       uci:t_set("olsr", "dyn_gw", "Library", "olsrd_dyn_gw.so.0.4")
                end
                
-               uci:set("olsr", "nameservice", nil, "LoadPlugin")
-               uci:set("olsr", "nameservice", "Library", "olsrd_nameservice.so.0.3")
-               uci:set("olsr", "nameservice", "name", ip:gsub("%.", "-"))
-               uci:set("olsr", "nameservice", "hosts_file", "/var/etc/hosts")
-               uci:set("olsr", "nameservice", "suffix", ".olsr")
-               uci:set("olsr", "nameservice", "latlon_infile", "/tmp/latlon.txt")
+               uci:t_set("olsr", "nameservice", nil, "LoadPlugin")
+               uci:t_set("olsr", "nameservice", "Library", "olsrd_nameservice.so.0.3")
+               uci:t_set("olsr", "nameservice", "name", ip:gsub("%.", "-"))
+               uci:t_set("olsr", "nameservice", "hosts_file", "/var/etc/hosts")
+               uci:t_set("olsr", "nameservice", "suffix", ".olsr")
+               uci:t_set("olsr", "nameservice", "latlon_infile", "/tmp/latlon.txt")
                
-               uci:set("olsr", "txtinfo", nil, "LoadPlugin")
-               uci:set("olsr", "txtinfo", "Library", "olsrd_txtinfo.so.0.1")
-               uci:set("olsr", "txtinfo", "Accept", "127.0.0.1")
+               uci:t_set("olsr", "txtinfo", nil, "LoadPlugin")
+               uci:t_set("olsr", "txtinfo", "Library", "olsrd_txtinfo.so.0.1")
+               uci:t_set("olsr", "txtinfo", "Accept", "127.0.0.1")
                
-               local oif = uci:add("olsr", "Interface")
-               uci:set("olsr", oif, "Interface", "ff")
-               uci:set("olsr", oif, "HelloInterval", "6.0")
-               uci:set("olsr", oif, "HelloValidityTime", "108.0")
-               uci:set("olsr", oif, "TcInterval", "4.0")
-               uci:set("olsr", oif, "TcValidityTime", "324.0")
-               uci:set("olsr", oif, "MidInterval", "18.0")
-               uci:set("olsr", oif, "MidValidityTime", "324.0")
-               uci:set("olsr", oif, "HnaInterval", "18.0")
-               uci:set("olsr", oif, "HnaValidityTime", "108.0")
+               local oif = uci:t_add("olsr", "Interface")
+               uci:t_set("olsr", oif, "Interface", "ff")
+               uci:t_set("olsr", oif, "HelloInterval", "6.0")
+               uci:t_set("olsr", oif, "HelloValidityTime", "108.0")
+               uci:t_set("olsr", oif, "TcInterval", "4.0")
+               uci:t_set("olsr", oif, "TcValidityTime", "324.0")
+               uci:t_set("olsr", oif, "MidInterval", "18.0")
+               uci:t_set("olsr", oif, "MidValidityTime", "324.0")
+               uci:t_set("olsr", oif, "HnaInterval", "18.0")
+               uci:t_set("olsr", oif, "HnaValidityTime", "108.0")
        end
        
        -- Configure Wifi
-       local wcfg = uci:sections("wireless")
+       local wcfg = uci:t_sections("wireless")
        if wcfg then
                for iface, v in pairs(wcfg) do
                        if v[".type"] == "wifi-device" and ffluci.http.formvalue("wifi."..iface) then
                                -- Cleanup
                                for k, j in pairs(wcfg) do
                                        if j[".type"] == "wifi-iface" and j.device == iface then
-                                               uci:del("wireless", k)
+                                               uci:t_del("wireless", k)
                                        end
                                end
                                
-                               uci:set("wireless", iface, "disabled", "0")
-                               uci:set("wireless", iface, "mode", "11g")
-                               uci:set("wireless", iface, "txantenna", 1)
-                               uci:set("wireless", iface, "rxantenna", 1)
-                               uci:set("wireless", iface, "channel", uci:get("freifunk", "community", "channel")) 
+                               uci:t_set("wireless", iface, "disabled", "0")
+                               uci:t_set("wireless", iface, "mode", "11g")
+                               uci:t_set("wireless", iface, "txantenna", 1)
+                               uci:t_set("wireless", iface, "rxantenna", 1)
+                               uci:t_set("wireless", iface, "channel", uci:t_get("freifunk", "community", "channel")) 
                                
-                               local wif = uci:add("wireless", "wifi-iface")
-                               uci:set("wireless", wif, "device", iface)
-                               uci:set("wireless", wif, "network", "ff")
-                               uci:set("wireless", wif, "mode", "adhoc")
-                               uci:set("wireless", wif, "ssid", uci:get("freifunk", "community", "essid"))
-                               uci:set("wireless", wif, "bssid", uci:get("freifunk", "community", "bssid"))
-                               uci:set("wireless", wif, "txpower", 13)
+                               local wif = uci:t_add("wireless", "wifi-iface")
+                               uci:t_set("wireless", wif, "device", iface)
+                               uci:t_set("wireless", wif, "network", "ff")
+                               uci:t_set("wireless", wif, "mode", "adhoc")
+                               uci:t_set("wireless", wif, "ssid", uci:t_get("freifunk", "community", "essid"))
+                               uci:t_set("wireless", wif, "bssid", uci:t_get("freifunk", "community", "bssid"))
+                               uci:t_set("wireless", wif, "txpower", 13)
                        end
                end
        end
-               
+       
+       -- Save UCI
+       uci:t_save("network")
+       uci:t_save("dhcp")
+       uci:t_save("freifunk")
+       uci:t_save("luci_splash")
+       uci:t_save("olsr")
+       uci:t_save("wireless")
 
        ffluci.http.redirect(ffluci.dispatcher.build_url("admin", "uci", "changes"))
 end
\ No newline at end of file
index 251107d..5c34e56 100644 (file)
@@ -10,16 +10,15 @@ function action_apply()
        if changes then
                local apply = {}
                
-               -- Collect files to be applied
+               -- Collect files to be applied and commit changes
                for i, line in ipairs(ffluci.util.split(changes)) do
                        local r = line:match("^-?([^.]+)")
                        if r and not ffluci.util.contains(apply, ffluci.config.uci_oncommit[r]) then
                                table.insert(apply, ffluci.config.uci_oncommit[r])
+                               ffluci.model.uci.commit(r)
                        end
                end
                
-               -- Commit changes
-               ffluci.model.uci.commit()
                
                -- Search for post-commit commands
                if ffluci.config.uci_oncommit then