Commit 5d3d6549 authored by Ted Trask's avatar Ted Trask
Browse files

Modified dnsmasq to change parameters to lists, allow for multiple entries in...

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.

git-svn-id: svn://svn.alpinelinux.org/acf/dnsmasq/trunk@1612 ab2d0c66-481e-0410-8bed-d214d4d58bed
parent f1f65ecc
APP_NAME=dnsmasq
PACKAGE=acf-$(APP_NAME)
VERSION=0.1.1
VERSION=0.1.0
APP_DIST=\
dnsmasq* \
......
......@@ -18,7 +18,36 @@ end %>
<H1>Config</H1>
<%
form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action
displayform(form)
displayformstart(form)
%>
<H2>General Parameters</H2>
<dl>
<%
displayformitem(form.value.interface, "interface")
displayformitem(form.value.listen_address, "listen_address")
displayformitem(form.value.domain, "domain")
%>
</dl>
<H2>DNS Parameters</H2>
<dl>
<%
displayformitem(form.value.mx_host, "mx_host")
%>
</dl>
<H2>DHCP Parameters</H2>
<dl>
<%
displayformitem(form.value.dhcp_range, "dhcp_range")
displayformitem(form.value.no_dhcp_interface, "no_dhcp_interface")
displayformitem(form.value.dhcp_host, "dhcp_host")
displayformitem(form.value.dhcp_option, "dhcp_option")
%>
</dl>
<%
displayformend(form)
%>
<% if viewlibrary and viewlibrary.dispatch_component then
......
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment