diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-11-26 15:03:26 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-11-26 15:03:26 +0000 |
commit | 5d3d65491dac81bf96d63e0fd8a5db25e4e5187c (patch) | |
tree | 848ae4e591945a4ea12e8c0dd7e395c6f94d973f /dnsmasq-model.lua | |
parent | f1f65ecc48666b798846e10b704bd4b7a057fc61 (diff) | |
download | acf-dnsmasq-5d3d65491dac81bf96d63e0fd8a5db25e4e5187c.tar.bz2 acf-dnsmasq-5d3d65491dac81bf96d63e0fd8a5db25e4e5187c.tar.xz |
Modified dnsmasq to change parameters to lists, allow for multiple entries in config file, and add some new parameters. Also remove a bunch of unused code.v0.1.0
git-svn-id: svn://svn.alpinelinux.org/acf/dnsmasq/trunk@1612 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'dnsmasq-model.lua')
-rw-r--r-- | dnsmasq-model.lua | 332 |
1 files changed, 164 insertions, 168 deletions
diff --git a/dnsmasq-model.lua b/dnsmasq-model.lua index cacb3d8..dbd600a 100644 --- a/dnsmasq-model.lua +++ b/dnsmasq-model.lua @@ -4,52 +4,169 @@ module(..., package.seeall) require("modelfunctions") require("fs") require("format") -require("posix") require("validator") -- Set variables local configfile = "/etc/dnsmasq.conf" local processname = "dnsmasq" local packagename = "dnsmasq" -local baseurl = "/etc/" -local descr = { -} -- ################################################################################ -- LOCAL FUNCTIONS -local function validateconfig(config) - local success = true - if config.value.IPSEND and not validator.is_ipv4(config.value.IPSEND.value) then - config.value.IPSEND.errtxt = "Invalid IP address" - success = false +local function update_file (file, search_name, value_in) + if not file or not search_name or search_name == "" then + return file, false end - if config.value.IP and not validator.is_ipv4(config.value.IP.value) then - config.value.IP.errtxt = "Invalid IP address" - success = false + + -- Since we clear out the value, this prevents us from changing parent's value + local value = value_in + if type(value_in) == "table" then + value = {} + for i,val in ipairs(value_in) do + value[#value + 1] = val + end end - return success, config + + local new_conf_file = {} + local skip_lines = {} + for l in string.gmatch(file, "([^\n]*)\n?") do + if string.find ( l, "\\%s*$" ) then + skip_lines[#skip_lines+1] = string.match(l, "^(.*)\\%s*$") + l = nil + else + if #skip_lines then + skip_lines[#skip_lines+1] = l + l = table.concat(skip_lines, " ") + end + -- check if comment line + if not string.find ( l, "^%s*#" ) then + -- find name + local a = string.match ( l, "^%s*([^=]*%S)%s*=" ) + if a and (search_name == a) then + -- Figure out the value + local b = string.match ( l, '=%s*(.*%S)%s*$' ) or "" + -- remove comments from end of line + if string.find ( b, '#' ) then + b = string.match ( b, '^(.*%S)%s*#.*$' ) or "" + end + + -- We found the name, change the value + if not value then + l = nil + elseif type(value) == "string" then + if value ~= b then + l = search_name.."="..value + end + value = nil + else + local temp = l + l = nil + for i,val in ipairs(value) do + if val == b then + l = temp + table.remove(value, i) + break + end + end + end + skip_lines = {} -- replacing line + end + end + if #skip_lines > 0 then + for i,line in ipairs(skip_lines) do + new_conf_file[#new_conf_file + 1] = line + end + skip_lines = {} + l = nil + end + end + new_conf_file[#new_conf_file + 1] = l + end + + if value then + -- we didn't find the searchname, add it now + if type(value) == "string" then + new_conf_file[#new_conf_file + 1] = search_name.."="..value + else + for i,val in ipairs(value) do + new_conf_file[#new_conf_file + 1] = search_name.."="..val + end + end + end + + file = table.concat(new_conf_file, '\n') + + return file, true end -local function validatedomain(domain) - local success = false - local domains = getDomains() - domain.value.domain.errtxt = "Invalid domain" - for i,name in ipairs(domains.value) do - if name == domain.value.domain.value then - domain.value.domain.errtxt = nil - success = true - break +-- Parse string for name=value pairs, returned in a table +local function parse_file (file) + if not file or file == "" then + return nil + end + local opts = nil + local skip_lines = {} + for l in string.gmatch(file, "([^\n]*)\n?") do + if string.find ( l, "\\%s*$" ) then + skip_lines[#skip_lines+1] = string.match(l, "^(.*)\\%s*$") + else + if #skip_lines then + skip_lines[#skip_lines+1] = l + l = table.concat(skip_lines, " ") + skip_lines = {} + end + -- check if comment line + if not string.find ( l, "^%s*#" ) then + -- find name + local a = string.match ( l, "^%s*([^=]*%S)%s*=" ) + if a then + -- Figure out the value + local b = string.match ( l, '=%s*(.*%S)%s*$' ) or "" + -- remove comments from end of line + if string.find ( b, '#' ) then + b = string.match ( b, '^(.*%S)%s*#.*$' ) or "" + end + + if not (opts) then opts = {} end + if not opts[a] then + opts[a] = {b} + else + table.insert(opts[a], b) + end + end + end end end - for i,name in ipairs(domain.value.iplist.value) do - if not validator.is_ipv4(name) then - domain.value.iplist.errtxt = "Invalid IP address" - success = false - break + + return opts +end + +local function validateconfig(config) + local success = true + + function testlist(param, test, errtxt) + if #param.value > 0 then + for i,val in ipairs(param.value) do + if test(val) then + param.errtxt = errtxt + success = false + break + end + end end end - return success, domain + + testlist(config.value.domain, function(v) return string.find(v, "%s") end, "Cannot contain spaces") + testlist(config.value.interface, function(v) return string.find(v, "%W") end, "Illegal character") + testlist(config.value.listen_address, function(v) return not validator.is_ipv4(v) end, "Invalid IP Address") + testlist(config.value.dhcp_range, function(v) return string.find(v, "%s") end, "Cannot contain spaces") + testlist(config.value.no_dhcp_interface, function(v) return string.find(v, "%W") end, "Illegal character") + testlist(config.value.dhcp_host, function(v) return string.find(v, "%s") end, "Cannot contain spaces") + testlist(config.value.dhcp_option, function(v) return string.find(v, "%s") end, "Cannot contain spaces") + testlist(config.value.mx_host, function(v) return string.find(v, "%s") end, "Cannot contain spaces") + + return success, config end -- ################################################################################ @@ -64,15 +181,19 @@ function getstatus() end function getconfig() - local conf = format.parse_ini_file(fs.read_file(configfile), "") or {} -require ("html") + local conf = parse_file(fs.read_file(configfile) or "") or {} local output = {} - output.DOMAIN = cfe({ value = conf.domain or "private.net", label="Local Domain to use", - descr="Internal Domain for your LAN" }) - output.INTERFACE = cfe({ value=conf.interface , label="Interface" }) - output.IP = cfe({ value=conf["listen-address"] or "", label="IP address to listen on" }) - output.RANGE = cfe ({value=conf["dhcp-range"] or "169.254.0.10,169.254.0.100,255.255.255.0,12h", label="Range of IPs", descr="First,Last,Netmask,Time in hours"}) + output.domain = cfe({ type="list", value=conf.domain or {}, label="Local Domain", + descr="List of internal domain(s) for your LAN 'domain[,address_range]'. Address range can be a single IP address, a range specified by 'IP,IP', or IP/netmask." }) + output.interface = cfe({ type="list", value=conf.interface or {}, label="Interface", descr="List of interfaces to listen on." }) + output.listen_address = cfe({ type="list", value=conf["listen-address"] or {}, label="List of IP addresses to listen on" }) + output.dhcp_range = cfe ({ type="list", value=conf["dhcp-range"] or {}, label="Range of DHCP IPs", + descr="List of Start,End,Netmask,Time in seconds/minutes(m)/hours(h) ie. 169.254.0.10,169.254.0.100,255.255.255.0,12h" }) + output.no_dhcp_interface = cfe({ type="list", value=conf["no-dhcp-interface"] or {}, label="No DHCP Interface", descr="List of interfaces which should have DNS but not DHCP." }) + output.dhcp_host = cfe({ type="list", value=conf["dhcp-host"] or {}, label="DHCP Host Parameter", descr="List of per host parameters for the DHCP server. See dnsmasq documentation." }) + output.dhcp_option = cfe({ type="list", value=conf["dhcp-option"] or {}, label="DHCP Option", descr="List of different or extra options to DHCP clients. See dnsmasq documentation." }) + output.mx_host = cfe({ type="list", value=conf["mx-host"] or {}, label="MX Record", descr="List of MX records 'mx_name,hostname'." }) -- APP.logevent(html.cfe_unpack(output)) @@ -84,10 +205,14 @@ function setconfig(config) if success then local file = fs.read_file(configfile) - file = format.update_ini_file(file,"","domain",config.value.DOMAIN.value) - file = format.update_ini_file(file,"","interface",config.value.INTERFACE.value) - file = format.update_ini_file(file,"","listen-address",config.value.IP.value) - file = format.update_ini_file(file,"","dhcp-range",config.value.RANGE.value) + file = update_file(file,"domain",config.value.domain.value) + file = update_file(file,"interface",config.value.interface.value) + file = update_file(file,"listen-address",config.value.listen_address.value) + file = update_file(file,"dhcp-range",config.value.dhcp_range.value) + file = update_file(file,"no-dhcp-interface",config.value.no_dhcp_interface.value) + file = update_file(file,"dhcp-host",config.value.dhcp_host.value) + file = update_file(file,"dhcp-option",config.value.dhcp_option.value) + file = update_file(file,"mx-host",config.value.mx_host.value) fs.write_file(configfile, file) else config.errtxt = "Failed to set config" @@ -106,132 +231,3 @@ function setconfigfile(filedetails) return modelfunctions.setfiledetails(filedetails, {configfile}) end -function getIPs() - local ipdir = baseurl.."ip" - local iplist = cfe({ type="list", value={}, label="IP prefixes to respond to" }) - if fs.is_dir(ipdir) then - for i,name in ipairs(posix.dir(ipdir)) do - if not string.match(name, "^%.") then - if (fs.is_file(ipdir.."/"..name)) then - table.insert(iplist.value, name) - end - end - end - end - return cfe({ type="group", value={iplist=iplist} }) -end - -function setIPs(iplist) - local reverseIPs = {} - for i,name in ipairs(iplist.value.iplist.value) do - -- check if a valid (or partial) ip - if not validator.is_partial_ipv4(name) then - iplist.value.iplist.errtxt = "Invalid IP address" - iplist.errtxt = "Failed to set IP list" - break - end - reverseIPs[name] = i - end - if not iplist.errtxt then - local currentIPlist = getIPs() - for i,name in ipairs(currentIPlist.value.iplist.value) do - if reverseIPs[name] then - reverseIPs[name] = nil - else - -- need to delete the file - local f = io.popen("rm "..baseurl.."ip/"..name) - f:close() - end - end - for name in pairs(reverseIPs) do - -- need to create the file - local f = io.popen("touch "..baseurl.."ip/"..name) - f:close() - end - end - return iplist -end - -function getDomains() - local domaindir = baseurl.."servers" - local domainlist = cfe({ type="list", value={}, label="DNS Server Domains" }) - if fs.is_dir(domaindir) then - for i,name in ipairs(posix.dir(domaindir)) do - if not string.match(name, "^%.") then - if (fs.is_file(domaindir.."/"..name)) then - table.insert(domainlist.value, name) - end - end - end - end - return domainlist -end - -function getNewDomain() - local domain = cfe({ label="Domain" }) - return cfe({ type="group", value={domain=domain} }) -end - -function setNewDomain(domain) - if "" ~= string.gsub(domain.value.domain.value..".", "%w+%.", "") then - domain.value.domain.errtxt = "Invalid domain" - domain.errtxt = "Failed to create domain" - elseif fs.is_file(baseurl.."servers/"..domain.value.domain.value) then - domain.value.domain.errtxt = "Domain already exists" - domain.errtxt = "Failed to create domain" - else - local f = io.popen("touch "..baseurl.."servers/"..domain.value.domain.value) - f:close() - domain.descr = "Created domain" - end - return domain -end - -function getDomain(getdomainname) - local domain = cfe({ value=getdomainname, label="Domain", errtxt="Invalid domain" }) - local iplist = cfe({ type="list", value={}, label="List of DNS servers" }) - local domains = getDomains() - for i,name in ipairs(domains.value) do - if name == getdomainname then - domain.errtxt = nil - break - end - end - if not domain.errtxt then - local content = fs.read_file(baseurl.."servers/"..getdomainname) - for name in string.gmatch(content.."\n", "([^\n]+)\n") do - table.insert(iplist.value, name) - end - end - return cfe({ type="group", value={domain=domain, iplist=iplist} }) -end - -function setDomain(domain) - local success, domain = validatedomain(domain) - if success then - fs.write_file(baseurl.."servers/"..domain.value.domain.value, - table.concat(domain.value.iplist.value, "\n") ) - else - domain.errtxt = "Failed to save domain" - end - return domain -end - -function deleteDomain(domainname) - local cmdresult = cfe({ value="Domain not deleted", label="Delete domain result", errtxt="Invalid domain" }) - local domains = getDomains() - if domainname == "@" then - cmdresult.errtxt = "Cannot delete root domain" - else - for i,name in ipairs(domains.value) do - if name == domainname then - local f = io.popen("rm "..baseurl.."servers/"..name) - f:close() - cmdresult.errtxt = nil - cmdresult.value = "Domain deleted" - break - end - end - end - return cmdresult -end |