libs: merge libs/uci into libs/core
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 12 Oct 2010 05:28:49 +0000 (05:28 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 12 Oct 2010 05:28:49 +0000 (05:28 +0000)
contrib/package/luci/Makefile
libs/core/luasrc/model/network.lua
libs/core/luasrc/model/uci.lua [new file with mode: 0644]
libs/core/luasrc/model/uci/bind.lua [new file with mode: 0644]
libs/core/root/etc/config/ucitrack [new file with mode: 0644]
libs/core/root/sbin/luci-reload [new file with mode: 0755]
libs/uci/luasrc/model/uci.lua [deleted file]
libs/uci/luasrc/model/uci/bind.lua [deleted file]
libs/uci/root/etc/config/ucitrack [deleted file]
libs/uci/root/sbin/luci-reload [deleted file]

index 70c7648..4099e51 100644 (file)
@@ -158,17 +158,6 @@ endif
 
 
 ### Libraries ###
-define Package/luci-uci
-  $(call Package/luci/libtemplate)
-  DEPENDS+=+libuci-lua
-  TITLE:=High-Level UCI API
-endef
-
-define Package/luci-uci/install
-       $(call Package/luci/install/template,$(1),libs/uci)
-endef
-
-
 define Package/luci-fastindex
   $(call Package/luci/libtemplate)
   TITLE:=Fastindex indexing module
@@ -315,7 +304,7 @@ endef
 
 define Package/luci-web
   $(call Package/luci/libtemplate)
-  DEPENDS+=+luci-sys +luci-nixio +luci-uci \
+  DEPENDS+=+luci-sys +luci-nixio +luci-core \
        +luci-sgi-cgi +luci-lmo
   TITLE:=MVC Webframework
   $(call Config,luci.main.lang,string,auto,Default Language)
@@ -332,7 +321,7 @@ endef
 
 define Package/luci-uvl
   $(call Package/luci/libtemplate)
-  DEPENDS+=+luci-sys +luci-uci +luci-core
+  DEPENDS+=+luci-sys +luci-core
   TITLE:=UVL - UCI Validation Layer
 endef
 
@@ -1075,9 +1064,6 @@ endif
 ifneq ($(CONFIG_PACKAGE_luci-px5g),)
        PKG_SELECTED_MODULES+=libs/px5g
 endif
-ifneq ($(CONFIG_PACKAGE_luci-uci),)
-       PKG_SELECTED_MODULES+=libs/uci
-endif
 ifneq ($(CONFIG_PACKAGE_luci-sys),)
        PKG_SELECTED_MODULES+=libs/sys
 endif
@@ -1292,7 +1278,6 @@ $(eval $(call BuildPackage,luci-luanet))
 $(eval $(call BuildPackage,luci-lucid))
 $(eval $(call BuildPackage,luci-nixio))
 $(eval $(call BuildPackage,luci-px5g))
-$(eval $(call BuildPackage,luci-uci))
 $(eval $(call BuildPackage,luci-sys))
 $(eval $(call BuildPackage,luci-web))
 $(eval $(call BuildPackage,luci-uvl))
index 8459463..53649dd 100644 (file)
@@ -483,3 +483,898 @@ function interface.get_network(self)
        end
 end
 
+--[==[
+#!/usr/bin/lua
+
+local uci = require "luci.model.uci".cursor_state()
+local utl = require "luci.util"
+local sys = require "luci.sys"
+local lip = require "luci.ip"
+local nxo = require "nixio"
+local nfs = require "nixio.fs"
+
+-- patch uci
+local x = getmetatable(uci)
+
+function x:list(...)
+       local val = self:get(...)
+       local lst = { }
+
+       if type(val) == "list" then
+               local _, v
+               for _, v in ipairs(val) do
+                       local i
+                       for i in v:gmatch("%S+") do
+                               lst[#lst+1] = i
+                       end
+               end
+       elseif type(val) == "string" then
+               local i
+               for i in val:gmatch("%S+") do
+                       lst[#lst+1] = i
+               end
+       end
+
+       return lst
+end
+
+
+system = utl.class()
+
+system._switches = { }
+system._vlans    = { }
+
+function system:__init__()
+       self._networks = { }
+
+       uci:foreach("network2", "interface",
+               function(s)
+                       self._networks[#self._networks+1] = system.network(s, self)
+               end)
+end
+
+function system:networks()
+       local index = 0
+       return function()
+               if index <= #self._networks then
+                       index = index + 1
+                       return self._networks[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system:find_network(name)
+       local v
+       for _, v in ipairs(self._networks) do
+               if v:name() == name then
+                       return v
+               end
+       end
+end
+
+function system:find_interface(name)
+       local v
+       for _, v in ipairs(self._networks) do
+               local i
+               for i in v:interfaces() do
+                       if i:is_bridge() then
+                               local p
+                               for p in i:interfaces() do
+                                       if p:name() == name then
+                                               return p
+                                       end
+                               end
+                       end
+
+                       if i:name() == name then
+                               return i
+                       end
+               end
+       end
+end
+
+function system:delete_network(name)
+       local i
+       for i = 1, #self._networks do
+               if self._networks[i]:name() == name then
+                       local x
+
+                       for x in self._networks[i]:aliases() do
+                               uci:delete("network2", x:name())
+                       end
+
+                       for x in self._networks[i]:routes() do
+                               uci:delete("network2", x:name())
+                       end
+
+                       uci:delete("network2", self._networks[i])
+                       table.remove(self._networks, i)
+
+                       return true
+               end
+       end
+       return false
+end
+
+function system:print()
+       local v
+       for v in self:networks() do
+               print(v:name())
+               v:print()
+               print("--")
+       end
+end
+
+function system.ignore_iface(ifn)
+       return (nil ~= (
+               ifn:match("^wlan%d") or 
+               ifn:match("^ath%d")  or
+               ifn:match("^wl%d")   or
+               ifn:match("^imq%d")  or
+               ifn:match("^br%-")   or
+               ifn:match("^/dev/")
+       ))
+end
+
+function system.find_wifi_networks(net)
+       local lst = { }
+       local cnt = 0
+
+       uci:foreach("wireless", "wifi-iface",
+               function(s)
+                       if s.device and s.network == net then
+                               lst[#lst+1] = { s.device, s['.name'], cnt }
+                       end
+                       cnt = cnt + 1
+               end)
+
+       return lst
+end
+
+function system.find_iface_names(net)
+       local lst = { }
+
+       local val = uci:list("network2", net, "device")
+       if #val == 0 or val[1]:match("^/dev/") then
+               val = uci:list("network2", net, "ifname")
+       end
+
+       local ifn
+       for _, ifn in ipairs(val) do
+               if not system.ignore_iface(ifn) then
+                       lst[#lst+1] = ifn
+               end
+       end
+       
+       return lst
+end
+
+function system.find_switch(name)
+       local swname, swdev, swvlan
+
+       -- find switch
+       uci:foreach("network2", "switch",
+               function(s)
+                       swname = s.name or s['.name']
+
+                       -- special: rtl8366s is eth0 (wan is eth1)
+                       if swname == "rtl8366s" then
+                               swdev = "eth0"
+
+                       -- special: rtl8366rb is eth0 (wan + lan)
+                       elseif swname == "rtl8366rb" then
+                               swdev = "eth0"
+
+                       -- treat swname as swdev
+                       else
+                               swdev = swname
+                       end
+
+                       return false
+               end)
+
+       -- find first vlan
+       if swdev then
+               uci:foreach("network2", "switch_vlan",
+                       function(s)
+                               if s.device == swname then
+                                       local vlan = tonumber(s.vlan)
+                                       if vlan and (not swvlan or vlan < swvlan) then
+                                               swvlan = vlan
+                                       end
+                               end
+                       end)
+       end
+
+
+       local veth, vlan = name:match("^(%S+)%.(%d+)$")
+
+       -- have vlan id and matching switch
+       if vlan and veth == swdev then
+               return swname, swdev, vlan
+
+       -- have no vlan id but matching switch, assume first switch vlan
+       elseif not vlan and name == swdev then
+               return swname, swdev, swvlan
+
+       -- have vlan and no matching switch, assume software vlan
+       elseif vlan then
+               return nil, veth, vlan
+       end
+end
+
+
+system.network = utl.class()
+
+function system.network:__init__(s, sys)
+       self._name    = s['.name']
+       self._sys     = sys
+       self._routes  = { }
+       self._aliases = { }
+
+       if s.type == "bridge" then
+               self._interfaces = { system.network.bridge(s['.name'], self) }
+       else
+               self._interfaces = { }
+
+               local ifn
+
+               -- find wired ifaces
+               for _, ifn in ipairs(system.find_iface_names(self._name)) do
+                       self._interfaces[#self._interfaces+1] = system.network.iface(ifn, self)
+               end
+
+               -- find wifi networks
+               for _, ifn in ipairs(system.find_wifi_networks(self._name)) do
+                       self._interfaces[#self._interfaces+1] = system.network.iface(ifn, self)
+               end
+       end
+
+       -- find ipv4 routes
+       uci:foreach("network2", "route",
+               function(s)
+                       if s.interface == self._name and s.target then
+                               self._routes[#self._routes+1] = system.network.route(s, self)
+                       end
+               end)
+
+       -- find ipv6 routes
+       uci:foreach("network2", "route6",
+               function(s)
+                       if s.interface == self._name and s.target then
+                               self._routes[#self._routes+1] = system.network.route(s, self)
+                       end
+               end)
+
+       -- find aliases
+       uci:foreach("network2", "alias",
+               function(s)
+                       if s.interface == self._name and s.proto then
+                               self._aliases[#self._aliases+1] = system.network.alias(s, self)
+                       end
+               end)
+end
+
+function system.network:name()
+       return self._name
+end
+
+function system.network:system()
+       return self._sys
+end
+
+function system.network:interfaces()
+       local index = 0
+       return function()
+               if index <= #self._interfaces then
+                       index = index + 1
+                       return self._interfaces[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system.network:interface()
+       return self._interfaces[1]
+end
+
+function system.network:num_routes()
+       return #self._routes
+end
+
+function system.network:routes()
+       local index = 0
+       return function()
+               if index <= #self._routes then
+                       index = index + 1
+                       return self._routes[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system.network:num_aliases()
+       return #self._aliases
+end
+
+function system.network:aliases()
+       local index = 0
+       return function()
+               if index <= #self._aliases then
+                       index = index + 1
+                       return self._aliases[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system.network:delete_route(rt)
+       local i
+       for i = 1, #self._routes do
+               if self._routes[i]:name() == rt:name() then
+                       uci:delete("network2", rt:name())
+                       table.remove(self._routes, i)
+                       return true
+               end
+       end
+       return false
+end
+
+function system.network:delete_alias(al)
+       local i
+       for i = 1, #self._aliases do
+               if self._aliases[i]:name() == al:name() then
+                       uci:delete("network2", al:name())
+                       table.remove(self._aliases, i)
+                       return true
+               end
+       end
+       return false
+end
+
+function system.network:print()
+       self:interface():print()
+end
+
+
+system.network.iface = utl.class()
+
+function system.network.iface:__init__(ifn, net, parent)
+       self._net    = net
+       self._parent = parent
+
+       -- is a wifi iface
+       if type(ifn) == "table" then
+               local wifidev, network, index = unpack(ifn)
+
+               self._name    = "%s.%d" %{ wifidev, index }
+               self._wifidev = wifidev
+               self._wifinet = index
+               self._ifname  = uci:get("wireless", network, "ifname") or self._name
+
+       -- is a wired iface
+       else
+               self._name   = ifn
+               self._ifname = ifn
+
+               local switch, swdev, vlan = system.find_switch(self._ifname)
+
+               if switch then
+                       self._switch = system.switch(switch, swdev, self)
+               end
+
+               if vlan then
+                       self._vlan = system.vlan(vlan, self._switch, self)
+               end
+       end
+end
+
+function system.network.iface:name()
+       return self._name
+end
+
+function system.network.iface:parent()
+       return self._parent
+end
+
+function system.network.iface:network()
+       return self._net
+end
+
+function system.network.iface:is_managed()
+       return (self._net ~= nil)
+end
+
+function system.network.iface:is_vlan()
+       return (self._vlan ~= nil)
+end
+
+function system.network.iface:is_software_vlan()
+       return (not self._switch and self._vlan ~= nil)
+end
+
+function system.network.iface:is_hardware_vlan()
+       return (self._switch ~= nil and self._vlan ~= nil)
+end
+
+function system.network.iface:_sysfs(path, default)
+       path = "/sys/class/net/%s/%s" %{ self._ifname, path }
+
+       local data = nfs.readfile(path)
+
+       if type(default) == "number" then
+               return tonumber(data) or default
+       elseif data and #data > 0 then
+               return data and data:gsub("%s+$", "") or default
+       end
+
+       return default
+end
+
+function system.network.iface:rx_bytes()
+       return self:_sysfs("statistics/rx_bytes", 0)
+end
+
+function system.network.iface:tx_bytes()
+       return self:_sysfs("statistics/tx_bytes", 0)
+end
+
+function system.network.iface:rx_packets()
+       return self:_sysfs("statistics/rx_packets", 0)
+end
+
+function system.network.iface:tx_packets()
+       return self:_sysfs("statistics/tx_packets", 0)
+end
+
+function system.network.iface:macaddr()
+       return self:_sysfs("address")
+end
+
+function system.network.iface:mtu()
+       return self:_sysfs("mtu", 1500)
+end
+
+function system.network.iface:is_bridge()
+       return (self:_sysfs("bridge/max_age", 0) > 0)
+end
+
+function system.network.iface:is_bridge_port()
+       return (self:_sysfs("brport/port_no", 0) > 0)
+end
+
+function system.network.iface:delete()
+       if self._wifidev then
+               local cnt = 0
+               uci:foreach("wireless", "wifi-iface", 
+                       function(s)
+                               cnt = cnt + 1
+                               if s.device == self._wifidev and cnt == self._wifinet then
+                                       uci:delete("wireless", s['.name'])
+                                       return false
+                               end
+                       end)
+       end
+end
+
+function system.network.iface:print()
+       if self._wifidev then
+               print("  wifi: ", self._wifidev, "net: ", self._wifinet)
+       else
+               print("  iface: ", self._name)
+       end
+
+       print("    rx: ", self:rx_bytes(), self:rx_packets())
+       print("    tx: ", self:tx_bytes(), self:tx_packets())
+       print("    mtu: ", self:mtu())
+       print("    mac: ", self:macaddr())
+       print("    bridge? ", self:is_bridge())
+       print("    port? ", self:is_bridge_port())
+       print("    swvlan? ", self:is_software_vlan())
+       print("    hwvlan? ", self:is_hardware_vlan())
+
+       if self._switch then
+               self._switch:print()
+       end
+
+       if self._vlan then
+               self._vlan:print()
+       end
+end
+
+
+system.network.bridge = utl.class(system.network.iface)
+
+function system.network.bridge:__init__(brn, net)
+       self._net    = net
+       self._name   = "br-" .. brn
+       self._ifname = self._name
+       self._interfaces = { }
+
+       local ifn
+
+       -- find wired ifaces
+       for _, ifn in ipairs(system.find_iface_names(brn)) do
+               self._interfaces[#self._interfaces+1] = system.network.iface(ifn, net, self)
+       end
+
+       -- find wifi networks
+       for _, ifn in ipairs(system.find_wifi_networks(brn)) do
+               self._interfaces[#self._interfaces+1] = system.network.iface(ifn, net, self)
+       end
+end
+
+function system.network.bridge:interfaces()
+       local index = 0
+       return function()
+               if index <= #self._interfaces then
+                       index = index + 1
+                       return self._interfaces[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system.network.bridge:print()
+       local v
+       for v in self:interfaces() do
+               io.write("  port: ")
+               v:print()
+       end
+       print("  rx: ", self:rx_bytes(), self:rx_packets())
+       print("  tx: ", self:tx_bytes(), self:tx_packets())
+       print("  mtu: ", self:mtu())
+       print("  mac: ", self:macaddr())
+       print("  bridge? ", self:is_bridge())
+       print("  port? ", self:is_bridge_port())
+end
+
+
+system.network.route = utl.class()
+
+function system.network.route:__init__(rt, net)
+       self._net    = net
+       self._name   = rt['.name']
+       self._ipv6   = (rt['.type'] == "route6")
+       self._mtu    = tonumber(rt.mtu) or (net and net:interface():mtu() or 1500)
+       self._metric = tonumber(rt.metric) or 0
+
+       if self._ipv6 then
+               self._gateway = lip.IPv6(rt.gateway or "::")
+               self._target  = lip.IPv6(rt.target  or "::")
+       else
+               self._gateway = lip.IPv4(rt.gateway or "0.0.0.0")
+               self._target  = lip.IPv4(rt.target  or "0.0.0.0", rt.netmask or "0.0.0.0")
+       end
+end
+
+function system.network.route:name()
+       return self._name
+end
+
+function system.network.route:network()
+       return self._net
+end
+
+function system.network.route:mtu()
+       return self._mtu
+end
+
+function system.network.route:metric()
+       return self._metric
+end
+
+function system.network.route:is_ipv4()
+       return not self._ipv6
+end
+
+function system.network.route:is_ipv6()
+       return self._ipv6
+end
+
+function system.network.route:target()
+       return self._target
+end
+
+function system.network.route:gateway()
+       return self._gateway
+end
+
+
+system.network.alias = utl.class()
+
+function system.network.alias:__init__(a, net)
+       self._net  = net
+       self._name = a['.name']
+end
+
+
+system.switch = utl.class()
+
+function system.switch:__init__(switch, swdev, net)
+       self._name   = switch
+       self._ifname = swdev
+       self._net    = net
+
+       if not system._switches[switch] then
+               local x = io.popen("swconfig dev %q help 2>/dev/null" % switch)
+               if x then
+                       local desc = x:read("*l")
+
+                       if desc then
+                               local name, num_ports, num_cpu, num_vlans =
+                                       desc:match("Switch %d: %S+%((.-)%), ports: (%d+) %(cpu @ (%d+)%), vlans: (%d+)")
+
+                               self._model   = name
+                               self._ports   = tonumber(num_ports)
+                               self._cpuport = tonumber(num_cpu)
+                               self._vlans   = tonumber(num_vlans)
+                       end
+
+                       x:close()
+
+               elseif nfs.access("/proc/switch/%s" % switch) then
+                       self._model   = self:_proc("driver", switch)
+                       self._ports   = self:_proc_count("port", 6)
+                       self._vlans   = self:_proc_count("vlan", 16)
+               end
+
+               -- defaults
+               self._model   = self._model   or switch
+               self._ports   = self._ports   or 6
+               self._vlans   = self._vlans   or 16
+               self._cpuport = self._cpuport or 5
+
+               system._switches[switch] = self
+       else
+               self._model   = system._switches[switch]._model
+               self._ports   = system._switches[switch]._ports
+               self._vlans   = system._switches[switch]._vlans
+               self._cpuport = system._switches[switch]._cpuport
+       end
+end
+
+function system.switch:_proc(path, default)
+       local data = nfs.readfile("/proc/switch/%s/%s" %{ self._name, path })
+       if data then
+               return data:gsub("%s+$", "")
+       end
+       return default
+end
+
+function system.switch:_proc_count(path, default)
+       local cnt = 0
+       for _ in nfs.dir("/proc/switch/%s/%s" %{ self._name, path }) do
+               cnt = cnt + 1
+       end
+       return cnt > 0 and cnt or default
+end
+
+function system.switch:name()
+       return self._name
+end
+
+function system.switch:model()
+       return self._model
+end
+
+function system.switch:num_possible_vlans()
+       return self._vlans
+end
+
+function system.switch:num_active_vlans()
+       local cnt = 0
+       uci:foreach("network2", "switch_vlan",
+               function(s)
+                       if s.device == self._name then cnt = cnt + 1 end
+               end)
+       return cnt
+end
+
+function system.switch:vlans()
+       local index = 0
+       local vlans = { }
+
+       uci:foreach("network2", "switch_vlan",
+               function(s)
+                       if s.device == self._name and tonumber(s.vlan) then
+                               vlans[#vlans+1] = tonumber(s.vlan)
+                       end
+               end)
+
+       return function()
+               if index <= #vlans then
+                       index = index + 1
+                       return system.vlan(vlans[index], self)
+               else
+                       return nil
+               end
+       end
+end
+
+function system.switch:num_ports()
+       return self._ports
+end
+
+function system.switch:delete_vlan(vlan)
+       local rv = false
+
+       uci:foreach("network2", "switch_vlan",
+               function(s)
+                       if s.device == self._name and tonumber(s.vlan) == vlan then
+                               rv = true
+                               uci:delete("network2", s['.name'])
+
+                               if system._vlans[s.device] and system._vlans[s.device][vlan] then
+                                       table.remove(system._vlans[s.device], vlan)
+                               end
+
+                               return false
+                       end
+               end)
+
+       return rv
+end
+
+function system.switch:print()
+       print("Switch:", self._model)
+       print("  Ports:", self._ports, "Cpu:", self._cpuport)
+       print("  Vlans:", self._vlans)
+end
+
+
+system.vlan = utl.class()
+
+function system.vlan:__init__(vlan, switch, iface)
+       self._vlan   = vlan
+       self._switch = switch
+       self._iface  = iface
+
+       local swid = (switch and switch:name()) or (iface and iface:name()) or ""
+
+       if not system._vlans[swid] or not system._vlans[swid][vlan] then
+               self._ports  = { }
+
+               if switch then
+                       uci:foreach("network2", "switch_vlan",
+                               function(s)
+                                       if s.device == switch:name() and tonumber(s.vlan) == vlan then
+                                               local p
+                                               for _, p in ipairs(uci:list("network2", s['.name'], "ports")) do
+                                                       self._ports[#self._ports+1] = system.vlan.port(p, self)
+                                               end
+                                               self._name = s['.name']
+                                       end
+                               end)
+               else
+                       self._ports[#self._ports+1] = system.vlan.port("0t", self)
+               end
+
+               system._vlans[swid] = system._vlans[swid] or { }
+               system._vlans[swid][vlan] = self
+       else
+               self._ports = system._vlans[swid][vlan]._ports
+       end
+end
+
+function system.vlan:name()
+       return self._name
+end
+
+function system.vlan:number()
+       return self._vlan
+end
+
+function system.vlan:switch()
+       return self._switch
+end
+
+function system.vlan:interface()
+       return self._iface
+end
+
+function system.vlan:is_software()
+       return (self._switch == nil)
+end
+
+function system.vlan:is_hardware()
+       return not self:is_software()
+end
+
+function system.vlan:num_ports()
+       return #self._ports
+end
+
+function system.vlan:ports()
+       local index = 0
+       return function()
+               if index <= #self._ports then
+                       index = index + 1
+                       return self._ports[index]
+               else
+                       return nil
+               end
+       end
+end
+
+function system.vlan:_update()
+       local i
+       local ports = { }
+
+       for i = 1, #self._ports do
+               ports[#ports+1] = self._ports[i]:string()
+       end
+
+       uci:set("network2", self._name, "ports", table.concat(ports, " "))
+end
+
+function system.vlan:delete_port(port)
+       if self._switch then
+               local i
+               for i = 1, #self._ports do
+                       if self._ports[i]:number() == port then
+                               table.remove(self._ports, i)
+                               self:_update()
+                               return true
+                       end
+               end
+       end
+       return false
+end
+
+function system.vlan:print()
+       print(" Vlan:", self._vlan, "Software?", self:is_software())
+       local p
+       for p in self:ports() do
+               p:print()
+       end
+end
+
+
+system.vlan.port = utl.class()
+
+function system.vlan.port:__init__(port, vlan)
+       local num, tag = port:match("^(%d+)([tu]?)")
+
+       self._vlan   = vlan
+       self._port   = tonumber(num)
+       self._tagged = (tag == "t")
+end
+
+function system.vlan.port:number()
+       return self._port
+end
+
+function system.vlan.port:vlan()
+       return self._vlan
+end
+
+function system.vlan.port:string()
+       return "%i%s" %{ self._port, self._tagged ? "t" : "" }
+end
+
+function system.vlan.port:is_tagged()
+       return self._tagged
+end
+
+function system.vlan.port:print()
+       print("  Port:", self._port, "Tagged:", self._tagged)
+end
+
+
+-- ------------------------------
+
+local s = system()
+
+s:print()
+
+s:find_network("wan"):print()
+s:find_interface("eth0"):parent():print()
+
+]==]
diff --git a/libs/core/luasrc/model/uci.lua b/libs/core/luasrc/model/uci.lua
new file mode 100644 (file)
index 0000000..66bd0a0
--- /dev/null
@@ -0,0 +1,345 @@
+--[[
+LuCI - UCI model
+
+Description:
+Generalized UCI model
+
+FileId:
+$Id$
+
+License:
+Copyright 2008 Steven Barth <steven@midlink.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+]]--
+local os    = require "os"
+local uci   = require "uci"
+local util  = require "luci.util"
+local table = require "table"
+
+
+local setmetatable, rawget, rawset = setmetatable, rawget, rawset
+local error, pairs, ipairs, tostring = error, pairs, ipairs, tostring
+local require, getmetatable, type = require, getmetatable, type
+
+--- LuCI UCI model library.
+-- The typical workflow for UCI is:  Get a cursor instance from the
+-- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
+-- save the changes to the staging area via Cursor.save and finally
+-- Cursor.commit the data to the actual config files.
+-- LuCI then needs to Cursor.apply the changes so deamons etc. are
+-- reloaded.
+-- @cstyle     instance
+module "luci.model.uci"
+
+--- Create a new UCI-Cursor.
+-- @class function
+-- @name cursor
+-- @return     UCI-Cursor
+cursor = uci.cursor
+
+APIVERSION = uci.APIVERSION
+
+--- Create a new Cursor initialized to the state directory.
+-- @return UCI cursor
+function cursor_state()
+       return cursor(nil, "/var/state")
+end
+
+
+inst = cursor()
+inst_state = cursor_state()
+
+local Cursor = getmetatable(inst)
+
+--- Applies UCI configuration changes
+-- @param configlist           List of UCI configurations
+-- @param command                      Don't apply only return the command
+function Cursor.apply(self, configlist, command)
+       configlist = self:_affected(configlist)
+       local reloadcmd = "/sbin/luci-reload " .. table.concat(configlist, " ")
+
+       return command and reloadcmd or os.execute(reloadcmd .. " >/dev/null 2>&1")
+end
+
+
+--- Delete all sections of a given type that match certain criteria.
+-- @param config               UCI config
+-- @param type                 UCI section type
+-- @param comparator   Function that will be called for each section and
+-- returns a boolean whether to delete the current section (optional)
+function Cursor.delete_all(self, config, stype, comparator)
+       local del = {}
+
+       if type(comparator) == "table" then
+               local tbl = comparator
+               comparator = function(section)
+                       for k, v in pairs(tbl) do
+                               if section[k] ~= v then
+                                       return false
+                               end
+                       end
+                       return true
+               end
+       end
+
+       local function helper (section)
+
+               if not comparator or comparator(section) then
+                       del[#del+1] = section[".name"]
+               end
+       end
+
+       self:foreach(config, stype, helper)
+
+       for i, j in ipairs(del) do
+               self:delete(config, j)
+       end
+end
+
+--- Create a new section and initialize it with data.
+-- @param config       UCI config
+-- @param type         UCI section type
+-- @param name         UCI section name (optional)
+-- @param values       Table of key - value pairs to initialize the section with
+-- @return                     Name of created section
+function Cursor.section(self, config, type, name, values)
+       local stat = true
+       if name then
+               stat = self:set(config, name, type)
+       else
+               name = self:add(config, type)
+               stat = name and true
+       end
+
+       if stat and values then
+               stat = self:tset(config, name, values)
+       end
+
+       return stat and name
+end
+
+--- Updated the data of a section using data from a table.
+-- @param config       UCI config
+-- @param section      UCI section name (optional)
+-- @param values       Table of key - value pairs to update the section with
+function Cursor.tset(self, config, section, values)
+       local stat = true
+       for k, v in pairs(values) do
+               if k:sub(1, 1) ~= "." then
+                       stat = stat and self:set(config, section, k, v)
+               end
+       end
+       return stat
+end
+
+--- Get a boolean option and return it's value as true or false.
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option
+-- @return                     Boolean
+function Cursor.get_bool(self, ...)
+       local val = self:get(...)
+       return ( val == "1" or val == "true" or val == "yes" or val == "on" )
+end
+
+--- Get an option or list and return values as table.
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option
+-- @return                     UCI value
+function Cursor.get_list(self, config, section, option)
+       if config and section and option then
+               local val = self:get(config, section, option)
+               return ( type(val) == "table" and val or { val } )
+       end
+       return nil
+end
+
+--- Set given values as list.
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option
+-- @param value                UCI value
+-- @return                     Boolean whether operation succeeded
+function Cursor.set_list(self, config, section, option, value)
+       if config and section and option then
+               return self:set(
+                       config, section, option,
+                       ( type(value) == "table" and value or { value } )
+               )
+       end
+       return false
+end
+
+-- Return a list of initscripts affected by configuration changes.
+function Cursor._affected(self, configlist)
+       configlist = type(configlist) == "table" and configlist or {configlist}
+
+       local c = cursor()
+       c:load("ucitrack")
+
+       -- Resolve dependencies
+       local reloadlist = {}
+
+       local function _resolve_deps(name)
+               local reload = {name}
+               local deps = {}
+
+               c:foreach("ucitrack", name,
+                       function(section)
+                               if section.affects then
+                                       for i, aff in ipairs(section.affects) do
+                                               deps[#deps+1] = aff
+                                       end
+                               end
+                       end)
+
+               for i, dep in ipairs(deps) do
+                       for j, add in ipairs(_resolve_deps(dep)) do
+                               reload[#reload+1] = add
+                       end
+               end
+
+               return reload
+       end
+
+       -- Collect initscripts
+       for j, config in ipairs(configlist) do
+               for i, e in ipairs(_resolve_deps(config)) do
+                       if not util.contains(reloadlist, e) then
+                               reloadlist[#reloadlist+1] = e
+                       end
+               end
+       end
+
+       return reloadlist
+end
+
+
+--- Add an anonymous section.
+-- @class function
+-- @name Cursor.add
+-- @param config       UCI config
+-- @param type         UCI section type
+-- @return                     Name of created section
+
+--- Get a table of saved but uncommitted changes.
+-- @class function
+-- @name Cursor.changes
+-- @param config       UCI config
+-- @return                     Table of changes
+-- @see Cursor.save
+
+--- Commit saved changes.
+-- @class function
+-- @name Cursor.commit
+-- @param config       UCI config
+-- @return                     Boolean whether operation succeeded
+-- @see Cursor.revert
+-- @see Cursor.save
+
+--- Deletes a section or an option.
+-- @class function
+-- @name Cursor.delete
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option (optional)
+-- @return                     Boolean whether operation succeeded
+
+--- Call a function for every section of a certain type.
+-- @class function
+-- @name Cursor.foreach
+-- @param config       UCI config
+-- @param type         UCI section type
+-- @param callback     Function to be called
+-- @return                     Boolean whether operation succeeded
+
+--- Get a section type or an option
+-- @class function
+-- @name Cursor.get
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option (optional)
+-- @return                     UCI value
+
+--- Get all sections of a config or all values of a section.
+-- @class function
+-- @name Cursor.get_all
+-- @param config       UCI config
+-- @param section      UCI section name (optional)
+-- @return                     Table of UCI sections or table of UCI values
+
+--- Manually load a config.
+-- @class function
+-- @name Cursor.load
+-- @param config       UCI config
+-- @return                     Boolean whether operation succeeded
+-- @see Cursor.save
+-- @see Cursor.unload
+
+--- Revert saved but uncommitted changes.
+-- @class function
+-- @name Cursor.revert
+-- @param config       UCI config
+-- @return                     Boolean whether operation succeeded
+-- @see Cursor.commit
+-- @see Cursor.save
+
+--- Saves changes made to a config to make them committable.
+-- @class function
+-- @name Cursor.save
+-- @param config       UCI config
+-- @return                     Boolean whether operation succeeded
+-- @see Cursor.load
+-- @see Cursor.unload
+
+--- Set a value or create a named section.
+-- @class function
+-- @name Cursor.set
+-- @param config       UCI config
+-- @param section      UCI section name
+-- @param option       UCI option or UCI section type
+-- @param value                UCI value or nil if you want to create a section
+-- @return                     Boolean whether operation succeeded
+
+--- Get the configuration directory.
+-- @class function
+-- @name Cursor.get_confdir
+-- @return                     Configuration directory
+
+--- Get the directory for uncomitted changes.
+-- @class function
+-- @name Cursor.get_savedir
+-- @return                     Save directory
+
+--- Set the configuration directory.
+-- @class function
+-- @name Cursor.set_confdir
+-- @param directory    UCI configuration directory
+-- @return                     Boolean whether operation succeeded
+
+--- Set the directory for uncommited changes.
+-- @class function
+-- @name Cursor.set_savedir
+-- @param directory    UCI changes directory
+-- @return                     Boolean whether operation succeeded
+
+--- Discard changes made to a config.
+-- @class function
+-- @name Cursor.unload
+-- @param config       UCI config
+-- @return                     Boolean whether operation succeeded
+-- @see Cursor.load
+-- @see Cursor.save
diff --git a/libs/core/luasrc/model/uci/bind.lua b/libs/core/luasrc/model/uci/bind.lua
new file mode 100644 (file)
index 0000000..9472dab
--- /dev/null
@@ -0,0 +1,173 @@
+--[[
+LuCI - UCI utilities for model classes
+
+Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+]]--
+
+local assert, pairs, type = assert, pairs, type
+local utl = require "luci.util"
+
+module "luci.model.uci.bind"
+
+bind = utl.class()
+
+function bind.__init__(self, config, cursor)
+       assert(config, "call to bind() without config file")
+       self.cfg = config
+       self.uci = cursor
+end
+
+function bind.init(self, cursor)
+       assert(cursor, "call to init() without uci cursor")
+       self.uci = cursor
+end
+
+function bind.section(self, stype)
+       local x = utl.class(bsection)
+       x.__init__ = function(inst, sid)
+               assert(self.uci:get(self.cfg, sid) == stype,
+                       "attempt to instantiate bsection(%q) of wrong type, expected %q"
+                       % { sid, stype })
+
+               inst.bind  = self
+               inst.stype = stype
+               inst.sid   = sid
+
+               if inst._init then
+                       inst:_init(sid)
+               end
+       end
+       return x
+end
+
+function bind.usection(self, stype)
+       local x = utl.class(bsection)
+       x.__init__ = function(inst)
+               inst.bind  = self
+               inst.stype = stype
+               inst.sid   = true
+       end
+       return x()
+end
+
+function bind.list(self, list, add, rem)
+       local lookup = { }
+
+       if type(list) == "string" then
+               local item
+               for item in list:gmatch("%S+") do
+                       lookup[item] = true
+               end
+
+       elseif type(list) == "table" then
+               local item
+               for _, item in pairs(list) do
+                       lookup[item] = true
+               end
+       end
+
+       if add then lookup[add] = true end
+       if rem then lookup[rem] = nil  end
+
+       return utl.keys(lookup)
+end
+
+function bind.bool(self, v)
+       return ( v == "1" or v == "true" or v == "yes" or v == "on" )
+end
+
+
+bsection = utl.class()
+
+function bsection.uciop(self, op, ...)
+       assert(self.bind and self.bind.uci,
+               "attempt to use unitialized binding")
+
+       if op then
+               return self.bind.uci[op](self.bind.uci, self.bind.cfg, ...)
+       else
+               return self.bind.uci
+       end
+end
+
+function bsection.get(self, k, c)
+       local v
+       if type(c) == "string" then
+               v = self:uciop("get", c, k)
+       else
+               self:uciop("foreach", self.stype,
+                       function(s)
+                               if type(c) == "table" then
+                                       local ck, cv
+                                       for ck, cv in pairs(c) do
+                                               if s[ck] ~= cv then return true end
+                                       end
+                               end
+                               if k ~= nil then
+                                       v = s[k]
+                               else
+                                       v = s
+                               end
+                               return false
+                       end)
+       end
+       return v
+end
+
+function bsection.set(self, k, v, c)
+       local stat
+       if type(c) == "string" then
+               if type(v) == "table" and #v == 0 then
+                       stat = self:uciop("delete", c, k)
+               else
+                       stat = self:uciop("set", c, k, v)
+               end
+       else
+               self:uciop("foreach", self.stype,
+                       function(s)
+                               if type(c) == "table" then
+                                       local ck, cv
+                                       for ck, cv in pairs(c) do
+                                               if s[ck] ~= cv then return true end
+                                       end
+                               end
+                               stat = self:uciop("set", c, k, v)
+                               return false
+                       end)
+       end
+       return stat or false
+end
+
+function bsection.property(self, k, n)
+       self[n or k] = function(c, val)
+               if val == nil then
+                       return c:get(k, c.sid)
+               else
+                       return c:set(k, val, c.sid)
+               end
+       end
+end
+
+function bsection.property_bool(self, k, n)
+       self[n or k] = function(c, val)
+               if val == nil then
+                       return bind:bool(c:get(k, c.sid))
+               else
+                       return c:set(k, bind:bool(val) and "1" or "0", c.sid)
+               end
+       end
+end
+
diff --git a/libs/core/root/etc/config/ucitrack b/libs/core/root/etc/config/ucitrack
new file mode 100644 (file)
index 0000000..7b47cc8
--- /dev/null
@@ -0,0 +1,48 @@
+config network
+       option init network
+       list affects dhcp
+
+config wireless
+       list affects network
+
+config firewall
+       option init firewall
+       list affects luci-splash
+       list affects qos
+
+config olsr
+       option init olsrd
+
+config dhcp
+       option init dnsmasq
+
+config dropbear
+       option init dropbear
+
+config httpd
+       option init httpd
+
+config fstab
+       option init fstab
+
+config qos
+       option init qos
+
+config system
+       option init led
+       list affects luci_statistics
+
+config luci_splash
+       option init luci_splash
+
+config upnpd
+       option init miniupnpd
+
+config ntpclient
+       option init ntpclient
+
+config samba
+       option init samba
+
+config tinyproxy
+       option init tinyproxy
diff --git a/libs/core/root/sbin/luci-reload b/libs/core/root/sbin/luci-reload
new file mode 100755 (executable)
index 0000000..24cf760
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+. /etc/functions.sh
+
+apply_config() {
+       config_get init "$1" init
+       config_get exec "$1" exec
+       config_get test "$1" test
+
+       echo "$2" > "/var/run/luci-reload-status"
+
+       [ -n "$init" ] && reload_init "$2" "$init" "$test"
+       [ -n "$exec" ] && reload_exec "$2" "$exec" "$test"
+}
+
+reload_exec() {
+       [ -x $2 ] && {
+               echo "Reloading $1... "
+               $2 >/dev/null 2>&1
+               [ -n "$3" -a "$?" != "$3" ] && echo '!!! Failed to reload' $1 '!!!'
+       }
+}
+
+reload_init() {
+       [ -x /etc/init.d/$2 ] && /etc/init.d/$2 enabled && {
+               echo "Reloading $1... "
+               /etc/init.d/$2 reload >/dev/null 2>&1
+               [ -n "$3" -a "$?" != "$3" ] && echo '!!! Failed to reload' $1 '!!!'
+       }
+}
+
+lock "/var/run/luci-reload"
+
+config_load ucitrack
+
+for i in $*; do
+       config_foreach apply_config $i $i
+done
+
+rm -f "/var/run/luci-reload-status"
+lock -u "/var/run/luci-reload"
diff --git a/libs/uci/luasrc/model/uci.lua b/libs/uci/luasrc/model/uci.lua
deleted file mode 100644 (file)
index 66bd0a0..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
---[[
-LuCI - UCI model
-
-Description:
-Generalized UCI model
-
-FileId:
-$Id$
-
-License:
-Copyright 2008 Steven Barth <steven@midlink.org>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-]]--
-local os    = require "os"
-local uci   = require "uci"
-local util  = require "luci.util"
-local table = require "table"
-
-
-local setmetatable, rawget, rawset = setmetatable, rawget, rawset
-local error, pairs, ipairs, tostring = error, pairs, ipairs, tostring
-local require, getmetatable, type = require, getmetatable, type
-
---- LuCI UCI model library.
--- The typical workflow for UCI is:  Get a cursor instance from the
--- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
--- save the changes to the staging area via Cursor.save and finally
--- Cursor.commit the data to the actual config files.
--- LuCI then needs to Cursor.apply the changes so deamons etc. are
--- reloaded.
--- @cstyle     instance
-module "luci.model.uci"
-
---- Create a new UCI-Cursor.
--- @class function
--- @name cursor
--- @return     UCI-Cursor
-cursor = uci.cursor
-
-APIVERSION = uci.APIVERSION
-
---- Create a new Cursor initialized to the state directory.
--- @return UCI cursor
-function cursor_state()
-       return cursor(nil, "/var/state")
-end
-
-
-inst = cursor()
-inst_state = cursor_state()
-
-local Cursor = getmetatable(inst)
-
---- Applies UCI configuration changes
--- @param configlist           List of UCI configurations
--- @param command                      Don't apply only return the command
-function Cursor.apply(self, configlist, command)
-       configlist = self:_affected(configlist)
-       local reloadcmd = "/sbin/luci-reload " .. table.concat(configlist, " ")
-
-       return command and reloadcmd or os.execute(reloadcmd .. " >/dev/null 2>&1")
-end
-
-
---- Delete all sections of a given type that match certain criteria.
--- @param config               UCI config
--- @param type                 UCI section type
--- @param comparator   Function that will be called for each section and
--- returns a boolean whether to delete the current section (optional)
-function Cursor.delete_all(self, config, stype, comparator)
-       local del = {}
-
-       if type(comparator) == "table" then
-               local tbl = comparator
-               comparator = function(section)
-                       for k, v in pairs(tbl) do
-                               if section[k] ~= v then
-                                       return false
-                               end
-                       end
-                       return true
-               end
-       end
-
-       local function helper (section)
-
-               if not comparator or comparator(section) then
-                       del[#del+1] = section[".name"]
-               end
-       end
-
-       self:foreach(config, stype, helper)
-
-       for i, j in ipairs(del) do
-               self:delete(config, j)
-       end
-end
-
---- Create a new section and initialize it with data.
--- @param config       UCI config
--- @param type         UCI section type
--- @param name         UCI section name (optional)
--- @param values       Table of key - value pairs to initialize the section with
--- @return                     Name of created section
-function Cursor.section(self, config, type, name, values)
-       local stat = true
-       if name then
-               stat = self:set(config, name, type)
-       else
-               name = self:add(config, type)
-               stat = name and true
-       end
-
-       if stat and values then
-               stat = self:tset(config, name, values)
-       end
-
-       return stat and name
-end
-
---- Updated the data of a section using data from a table.
--- @param config       UCI config
--- @param section      UCI section name (optional)
--- @param values       Table of key - value pairs to update the section with
-function Cursor.tset(self, config, section, values)
-       local stat = true
-       for k, v in pairs(values) do
-               if k:sub(1, 1) ~= "." then
-                       stat = stat and self:set(config, section, k, v)
-               end
-       end
-       return stat
-end
-
---- Get a boolean option and return it's value as true or false.
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option
--- @return                     Boolean
-function Cursor.get_bool(self, ...)
-       local val = self:get(...)
-       return ( val == "1" or val == "true" or val == "yes" or val == "on" )
-end
-
---- Get an option or list and return values as table.
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option
--- @return                     UCI value
-function Cursor.get_list(self, config, section, option)
-       if config and section and option then
-               local val = self:get(config, section, option)
-               return ( type(val) == "table" and val or { val } )
-       end
-       return nil
-end
-
---- Set given values as list.
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option
--- @param value                UCI value
--- @return                     Boolean whether operation succeeded
-function Cursor.set_list(self, config, section, option, value)
-       if config and section and option then
-               return self:set(
-                       config, section, option,
-                       ( type(value) == "table" and value or { value } )
-               )
-       end
-       return false
-end
-
--- Return a list of initscripts affected by configuration changes.
-function Cursor._affected(self, configlist)
-       configlist = type(configlist) == "table" and configlist or {configlist}
-
-       local c = cursor()
-       c:load("ucitrack")
-
-       -- Resolve dependencies
-       local reloadlist = {}
-
-       local function _resolve_deps(name)
-               local reload = {name}
-               local deps = {}
-
-               c:foreach("ucitrack", name,
-                       function(section)
-                               if section.affects then
-                                       for i, aff in ipairs(section.affects) do
-                                               deps[#deps+1] = aff
-                                       end
-                               end
-                       end)
-
-               for i, dep in ipairs(deps) do
-                       for j, add in ipairs(_resolve_deps(dep)) do
-                               reload[#reload+1] = add
-                       end
-               end
-
-               return reload
-       end
-
-       -- Collect initscripts
-       for j, config in ipairs(configlist) do
-               for i, e in ipairs(_resolve_deps(config)) do
-                       if not util.contains(reloadlist, e) then
-                               reloadlist[#reloadlist+1] = e
-                       end
-               end
-       end
-
-       return reloadlist
-end
-
-
---- Add an anonymous section.
--- @class function
--- @name Cursor.add
--- @param config       UCI config
--- @param type         UCI section type
--- @return                     Name of created section
-
---- Get a table of saved but uncommitted changes.
--- @class function
--- @name Cursor.changes
--- @param config       UCI config
--- @return                     Table of changes
--- @see Cursor.save
-
---- Commit saved changes.
--- @class function
--- @name Cursor.commit
--- @param config       UCI config
--- @return                     Boolean whether operation succeeded
--- @see Cursor.revert
--- @see Cursor.save
-
---- Deletes a section or an option.
--- @class function
--- @name Cursor.delete
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option (optional)
--- @return                     Boolean whether operation succeeded
-
---- Call a function for every section of a certain type.
--- @class function
--- @name Cursor.foreach
--- @param config       UCI config
--- @param type         UCI section type
--- @param callback     Function to be called
--- @return                     Boolean whether operation succeeded
-
---- Get a section type or an option
--- @class function
--- @name Cursor.get
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option (optional)
--- @return                     UCI value
-
---- Get all sections of a config or all values of a section.
--- @class function
--- @name Cursor.get_all
--- @param config       UCI config
--- @param section      UCI section name (optional)
--- @return                     Table of UCI sections or table of UCI values
-
---- Manually load a config.
--- @class function
--- @name Cursor.load
--- @param config       UCI config
--- @return                     Boolean whether operation succeeded
--- @see Cursor.save
--- @see Cursor.unload
-
---- Revert saved but uncommitted changes.
--- @class function
--- @name Cursor.revert
--- @param config       UCI config
--- @return                     Boolean whether operation succeeded
--- @see Cursor.commit
--- @see Cursor.save
-
---- Saves changes made to a config to make them committable.
--- @class function
--- @name Cursor.save
--- @param config       UCI config
--- @return                     Boolean whether operation succeeded
--- @see Cursor.load
--- @see Cursor.unload
-
---- Set a value or create a named section.
--- @class function
--- @name Cursor.set
--- @param config       UCI config
--- @param section      UCI section name
--- @param option       UCI option or UCI section type
--- @param value                UCI value or nil if you want to create a section
--- @return                     Boolean whether operation succeeded
-
---- Get the configuration directory.
--- @class function
--- @name Cursor.get_confdir
--- @return                     Configuration directory
-
---- Get the directory for uncomitted changes.
--- @class function
--- @name Cursor.get_savedir
--- @return                     Save directory
-
---- Set the configuration directory.
--- @class function
--- @name Cursor.set_confdir
--- @param directory    UCI configuration directory
--- @return                     Boolean whether operation succeeded
-
---- Set the directory for uncommited changes.
--- @class function
--- @name Cursor.set_savedir
--- @param directory    UCI changes directory
--- @return                     Boolean whether operation succeeded
-
---- Discard changes made to a config.
--- @class function
--- @name Cursor.unload
--- @param config       UCI config
--- @return                     Boolean whether operation succeeded
--- @see Cursor.load
--- @see Cursor.save
diff --git a/libs/uci/luasrc/model/uci/bind.lua b/libs/uci/luasrc/model/uci/bind.lua
deleted file mode 100644 (file)
index 9472dab..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
---[[
-LuCI - UCI utilities for model classes
-
-Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-]]--
-
-local assert, pairs, type = assert, pairs, type
-local utl = require "luci.util"
-
-module "luci.model.uci.bind"
-
-bind = utl.class()
-
-function bind.__init__(self, config, cursor)
-       assert(config, "call to bind() without config file")
-       self.cfg = config
-       self.uci = cursor
-end
-
-function bind.init(self, cursor)
-       assert(cursor, "call to init() without uci cursor")
-       self.uci = cursor
-end
-
-function bind.section(self, stype)
-       local x = utl.class(bsection)
-       x.__init__ = function(inst, sid)
-               assert(self.uci:get(self.cfg, sid) == stype,
-                       "attempt to instantiate bsection(%q) of wrong type, expected %q"
-                       % { sid, stype })
-
-               inst.bind  = self
-               inst.stype = stype
-               inst.sid   = sid
-
-               if inst._init then
-                       inst:_init(sid)
-               end
-       end
-       return x
-end
-
-function bind.usection(self, stype)
-       local x = utl.class(bsection)
-       x.__init__ = function(inst)
-               inst.bind  = self
-               inst.stype = stype
-               inst.sid   = true
-       end
-       return x()
-end
-
-function bind.list(self, list, add, rem)
-       local lookup = { }
-
-       if type(list) == "string" then
-               local item
-               for item in list:gmatch("%S+") do
-                       lookup[item] = true
-               end
-
-       elseif type(list) == "table" then
-               local item
-               for _, item in pairs(list) do
-                       lookup[item] = true
-               end
-       end
-
-       if add then lookup[add] = true end
-       if rem then lookup[rem] = nil  end
-
-       return utl.keys(lookup)
-end
-
-function bind.bool(self, v)
-       return ( v == "1" or v == "true" or v == "yes" or v == "on" )
-end
-
-
-bsection = utl.class()
-
-function bsection.uciop(self, op, ...)
-       assert(self.bind and self.bind.uci,
-               "attempt to use unitialized binding")
-
-       if op then
-               return self.bind.uci[op](self.bind.uci, self.bind.cfg, ...)
-       else
-               return self.bind.uci
-       end
-end
-
-function bsection.get(self, k, c)
-       local v
-       if type(c) == "string" then
-               v = self:uciop("get", c, k)
-       else
-               self:uciop("foreach", self.stype,
-                       function(s)
-                               if type(c) == "table" then
-                                       local ck, cv
-                                       for ck, cv in pairs(c) do
-                                               if s[ck] ~= cv then return true end
-                                       end
-                               end
-                               if k ~= nil then
-                                       v = s[k]
-                               else
-                                       v = s
-                               end
-                               return false
-                       end)
-       end
-       return v
-end
-
-function bsection.set(self, k, v, c)
-       local stat
-       if type(c) == "string" then
-               if type(v) == "table" and #v == 0 then
-                       stat = self:uciop("delete", c, k)
-               else
-                       stat = self:uciop("set", c, k, v)
-               end
-       else
-               self:uciop("foreach", self.stype,
-                       function(s)
-                               if type(c) == "table" then
-                                       local ck, cv
-                                       for ck, cv in pairs(c) do
-                                               if s[ck] ~= cv then return true end
-                                       end
-                               end
-                               stat = self:uciop("set", c, k, v)
-                               return false
-                       end)
-       end
-       return stat or false
-end
-
-function bsection.property(self, k, n)
-       self[n or k] = function(c, val)
-               if val == nil then
-                       return c:get(k, c.sid)
-               else
-                       return c:set(k, val, c.sid)
-               end
-       end
-end
-
-function bsection.property_bool(self, k, n)
-       self[n or k] = function(c, val)
-               if val == nil then
-                       return bind:bool(c:get(k, c.sid))
-               else
-                       return c:set(k, bind:bool(val) and "1" or "0", c.sid)
-               end
-       end
-end
-
diff --git a/libs/uci/root/etc/config/ucitrack b/libs/uci/root/etc/config/ucitrack
deleted file mode 100644 (file)
index 7b47cc8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-config network
-       option init network
-       list affects dhcp
-
-config wireless
-       list affects network
-
-config firewall
-       option init firewall
-       list affects luci-splash
-       list affects qos
-
-config olsr
-       option init olsrd
-
-config dhcp
-       option init dnsmasq
-
-config dropbear
-       option init dropbear
-
-config httpd
-       option init httpd
-
-config fstab
-       option init fstab
-
-config qos
-       option init qos
-
-config system
-       option init led
-       list affects luci_statistics
-
-config luci_splash
-       option init luci_splash
-
-config upnpd
-       option init miniupnpd
-
-config ntpclient
-       option init ntpclient
-
-config samba
-       option init samba
-
-config tinyproxy
-       option init tinyproxy
diff --git a/libs/uci/root/sbin/luci-reload b/libs/uci/root/sbin/luci-reload
deleted file mode 100755 (executable)
index 24cf760..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-. /etc/functions.sh
-
-apply_config() {
-       config_get init "$1" init
-       config_get exec "$1" exec
-       config_get test "$1" test
-
-       echo "$2" > "/var/run/luci-reload-status"
-
-       [ -n "$init" ] && reload_init "$2" "$init" "$test"
-       [ -n "$exec" ] && reload_exec "$2" "$exec" "$test"
-}
-
-reload_exec() {
-       [ -x $2 ] && {
-               echo "Reloading $1... "
-               $2 >/dev/null 2>&1
-               [ -n "$3" -a "$?" != "$3" ] && echo '!!! Failed to reload' $1 '!!!'
-       }
-}
-
-reload_init() {
-       [ -x /etc/init.d/$2 ] && /etc/init.d/$2 enabled && {
-               echo "Reloading $1... "
-               /etc/init.d/$2 reload >/dev/null 2>&1
-               [ -n "$3" -a "$?" != "$3" ] && echo '!!! Failed to reload' $1 '!!!'
-       }
-}
-
-lock "/var/run/luci-reload"
-
-config_load ucitrack
-
-for i in $*; do
-       config_foreach apply_config $i $i
-done
-
-rm -f "/var/run/luci-reload-status"
-lock -u "/var/run/luci-reload"