diff options
author | Natanael Copa <natanael.copa@gmail.com> | 2008-02-05 10:21:09 +0000 |
---|---|---|
committer | Natanael Copa <natanael.copa@gmail.com> | 2008-02-05 10:21:09 +0000 |
commit | cf5e02febbb87497ae7f5477928d0358fee6885c (patch) | |
tree | fe17e7c6d22fed2a3e142f457502076c05d8c896 /prototypejsdemo-model.lua | |
parent | 0818e8ec1ce0a2e3f71e7b0e551e0f4071ebfd2d (diff) | |
download | acf-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.lua | 284 |
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 + + |