summaryrefslogtreecommitdiffstats
path: root/prototypejsdemo-model.lua
diff options
context:
space:
mode:
authorNatanael Copa <natanael.copa@gmail.com>2008-02-05 10:21:09 +0000
committerNatanael Copa <natanael.copa@gmail.com>2008-02-05 10:21:09 +0000
commitcf5e02febbb87497ae7f5477928d0358fee6885c (patch)
treefe17e7c6d22fed2a3e142f457502076c05d8c896 /prototypejsdemo-model.lua
parent0818e8ec1ce0a2e3f71e7b0e551e0f4071ebfd2d (diff)
downloadacf-sandbox-cf5e02febbb87497ae7f5477928d0358fee6885c.tar.bz2
acf-sandbox-cf5e02febbb87497ae7f5477928d0358fee6885c.tar.xz
added prototype demo
git-svn-id: svn://svn.alpinelinux.org/acf/sandbox/trunk@692 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'prototypejsdemo-model.lua')
-rw-r--r--prototypejsdemo-model.lua284
1 files changed, 284 insertions, 0 deletions
diff --git a/prototypejsdemo-model.lua b/prototypejsdemo-model.lua
new file mode 100644
index 0000000..b0d3b05
--- /dev/null
+++ b/prototypejsdemo-model.lua
@@ -0,0 +1,284 @@
+-- acf model for /etc/network/interfaces
+-- Copyright(c) 2007 N. Angelacos - Licensed under terms of GPL2
+module (..., package.seeall)
+
+-- iface is a local (private) table with private methods for managing
+-- the interfaces file. All low-level stuff is done here. It exposes
+-- the iface.tags, file(raw), and array (parsed), as well as a number
+-- of functions for managing the interface file. These are in a local
+-- table because nobody outside the model should know anything about
+-- the interfaces file (not even where it is - it could be in an LDAP
+-- directory for all we know) The public module functions are defined
+-- further below
+
+local iface = { tags = { "name", "comment", "method", "address",
+ "netmask", "gateway", "hostname", "provider",
+ "pre-up", "up", "down", "post-down" },
+ methods = { "dhcp", "static", "ppp", "loopback", "manual" },
+ -- lowlevel functions will insert file and array here
+ }
+
+
+-- Lowlevel functions - they do things directly to iface.
+iface.read_file = function ()
+ local filename = "/etc/network/interfaces"
+ iface.file = cfe { name=filename, filename=filename }
+ local file = io.open(filename)
+ local rc = false
+ if file then
+ iface.file.value = file:read("*a")
+ -- make sure it has a terminating \n
+ iface.file.value = string.gsub (iface.file.value, "([^\n])$", "%1\n")
+ file:close()
+ rc = true
+ end
+ return rc
+end
+
+iface.write_file = function ()
+ local rc = false
+ local file = io.open ( iface.file.name, "w")
+ if file then
+ file:write ( iface.file.value )
+ file:close()
+ rc = true
+ end
+ return rc
+ end
+
+function iface.iface_type ( )
+ local f = {}
+ for k,v in pairs(iface.tags) do
+ f[v] = cfe { name = v }
+ end
+
+
+ for k,v in pairs ({"comment", "pre-up", "up", "down", "post-down"}) do
+ f[v].type ="longtext"
+ end
+
+ f.method.type = "select"
+ f.method.option = iface.methods
+ return (f)
+end
+
+-- return true or false + the index of iface.array matching "name"
+function iface.index (name)
+ if name== nil or #name == 0 then
+ return true, 0
+ end
+
+ if iface.array == nil then
+ iface.unpack_interfaces ()
+ end
+
+ for k,v in ipairs(iface.array) do
+ if name == v.name.value then
+ return true, k
+ end
+ end
+
+ return false, 0
+end
+
+
+function iface.append ( self, value, prefix )
+ self = self or ""
+ -- if we already have some values, then append a newline
+ if #self > 0 then self = self .. "\n" end
+ -- strip the prefix
+ local str = string.gsub(value, "^" .. ( prefix or "" ), "")
+ -- and append
+ return self .. str
+end
+
+function iface.expand ( self, prefix )
+ if #self == 0 then
+ return ""
+ end
+ -- force the string to end in a single linefeed
+ self = string.gsub (self, "\r", "")
+ self = string.gsub (self, "[\n]*$", "\n")
+ local str = ""
+ for line in string.gmatch ( self, ".-\n") do
+ if #line > 0 then
+ str = str .. prefix .. " " .. line
+ end
+ end
+ return str
+end
+
+function iface.unpack_interfaces ()
+ if iface.array == nil then
+ iface.read_file()
+ iface.array = {}
+ end
+
+ -- call it array so we don't have to call it iface.array everywhere
+ local array = iface.array
+ local count = 0
+
+ array[count] = iface.iface_type()
+
+ for line in string.gmatch ( iface.file.value, ".-\n") do
+ -- strip leading spaces, tabs
+ line = string.gsub (line, "^[%s]*", "")
+ line = string.gsub (line, "\n*$", "")
+ -- it can be #, auto, iface, or a parameter
+ if string.match(line, "^#") then
+ array[count].comment.value =
+ iface.append(array[count].comment.value, line , "#%s*" )
+ elseif string.match(line, "^auto") then
+ -- do nothing
+ elseif string.match(line, "^iface") then
+ count = count + 1
+ array[count] = iface.iface_type()
+ -- iface <name> [inet | ipx] <method> -- we assume inet
+ array[count].name.value,
+ array[count].method.value =
+ string.match(line, "%w+%s+(%w+)%s+%w+%s+(%w+)")
+ else -- it must be some kind of parameter
+ local param, val =
+ string.match(line, "(%S+)%s*(.*)$")
+ if (param) then
+ array[count][param].value =
+ iface.append (array[count][param].value, val)
+ end
+ end
+ end
+
+ -- now move the comments to go with the interface
+ for n = count,1,-1 do
+ array[n].comment.value = array[n-1].comment.value
+ end
+
+ return array
+end
+
+function iface.pack_interfaces()
+ local str = ""
+ for n = 1,#iface.array,1 do
+ local me = iface.array[n]
+ for k,v in pairs (iface.tags) do
+ if v == "comment" then
+ str = str .. "\n" .. iface.expand ( me[v].value, "#")
+ elseif v == "method" then
+ str = str .. string.format ("\nauto %s\niface %s inet %s\n",
+ me.name.value, me.name.value,
+ me.method.value)
+ elseif v == "name" then
+ -- nothing
+ else
+ str = str .. iface.expand( me[v].value, "\t" .. v)
+ end
+ end
+ end
+ return str
+end
+
+function iface.commit()
+ iface.file.value = iface.pack_interfaces()
+ return iface.write_file()
+end
+
+
+function iface.add_after ( name, def )
+ -- if the new if.name is already in the table, then fail
+ local rc, idx = iface.index(def.name.value)
+ if idx > 0 then
+ def.name.errtxt = "This interface is already defined"
+ return false, def
+ end
+
+ -- if the name to insert after doesn't exist, just fail
+ rc, idx = iface.index(name)
+ if rc == false then
+ return false, def
+ end
+
+ rc, def = iface.validate (def)
+ if rc == false then
+ return rc, def
+ end
+
+ table.insert( iface.array, idx+1, def )
+ return iface.commit() , def
+end
+
+function iface.read ( name )
+ -- if the name is blank, then return an empty def
+ local rc, idx = iface.index(name or "")
+ if name == nil or #name == 0 or rc == false then
+ return rc, iface.iface_type()
+ end
+ return iface.commit(), iface.array[idx]
+end
+
+
+function iface.update ( def)
+ -- if the def by that name doesn't exist, fail
+ local rc, idx = iface.index(def.name.value or "" )
+ if idx == 0 then
+ def.name.errtxt = "This is an invalid interface name"
+ return false, def
+ end
+
+ rc, def = iface.validate ( def )
+ if rc == false then
+ return rc, def
+ end
+
+ iface.array[idx] = def
+ return iface.commit(), def
+end
+
+function iface.delete (name )
+ local rc, idx = iface.index(name or "" )
+ if idx == 0 then
+ rc = false
+ else
+ table.remove (iface.array, idx )
+ end
+ return iface.commit()
+end
+
+
+iface.validate = function ( def )
+ if #def.name.value == 0 then
+ iface.name.errtxt = "The interface must have a name"
+ end
+ def.method.errtxt = "Method specified is invalid"
+ for k,v in pairs (iface.methods) do
+ if def.method.value == v then
+ def.method.errtxt = ""
+ end
+ end
+ -- More validation tests go here ---
+ --
+ local rc = true
+ for k,v in pairs(def) do
+ if #def[k].errtxt > 0 then result = false end
+ end
+
+ return result, def
+end
+
+-------------------------------------------------------------------------------
+-- Public Methods
+-------------------------------------------------------------------------------
+
+get_all_interfaces = iface.unpack_interfaces
+
+get_iface_by_name = iface.read
+
+create_iface_by_name = iface.add_after
+
+update_iface_by_name = function (def, name )
+ -- make sure name we think we are updating is name we are updating
+ def.name.value = name
+ return iface.update (def)
+end
+
+delete_iface_by_name = iface.delete
+
+