summaryrefslogtreecommitdiffstats
path: root/dnscache-model.lua
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-06-26 19:16:25 +0000
committerTed Trask <ttrask01@yahoo.com>2008-06-26 19:16:25 +0000
commit337584d2a16c3a22551ab31c6eff7beb1c942815 (patch)
treeaf0e254f7f4ba070f087fa722b9c513152f9e55c /dnscache-model.lua
parent30aaf3f8be724ddbf38dfe5c67b0123cd07d7e1d (diff)
downloadacf-dnscache-337584d2a16c3a22551ab31c6eff7beb1c942815.tar.bz2
acf-dnscache-337584d2a16c3a22551ab31c6eff7beb1c942815.tar.xz
Rewrite of DNScache.
git-svn-id: svn://svn.alpinelinux.org/acf/dnscache/trunk@1262 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'dnscache-model.lua')
-rw-r--r--dnscache-model.lua349
1 files changed, 220 insertions, 129 deletions
diff --git a/dnscache-model.lua b/dnscache-model.lua
index 649fcc5..fc41cc6 100644
--- a/dnscache-model.lua
+++ b/dnscache-model.lua
@@ -30,180 +30,271 @@ local function process_status_text(procname)
end
end
-local function humanreadable(value)
- local myvalue = tonumber(value)
- if not (myvalue) then
- return false
- end
- if ( myvalue > 1073741824 ) then
- myvalue=((myvalue/1073741824) - (myvalue/1073741824%0.1)) .. "G"
- elseif ( myvalue > 1048576 ) then
- myvalue=((myvalue/1048576) - (myvalue/1048576%0.1)) .. "M"
- elseif ( myvalue > 1024 ) then
- myvalue=((myvalue/1024) - (myvalue/1024%0.1)) .. "k"
- end
- return myvalue
-end
-
-local function list_servers()
- local serverlist = {}
- local serverdetails = {}
- for k,v in pairs(posix.dir(baseurl .. "servers")) do
- if not string.match(v, "^%.") then
- if (fs.is_file(baseurl .. "servers/" .. v)) then
- table.insert(serverlist, v)
- serverdetails[v] = fs.read_file_as_array(baseurl .. "servers/" .. v)
- end
+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
+ end
+ if config.value.CACHESIZE and not validator.is_integer(config.value.CACHESIZE.value) then
+ config.value.CACHESIZE.errtxt = "Must be an integer"
+ success = 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
+ end
+ return success, config
+end
+
+local function getfiledetails(file)
+ local filename = cfe({ value=file, label="File name" })
+ local filecontent = cfe({ type="longtext", label="File content" })
+ local filesize = cfe({ value="0", label="File size" })
+ local mtime = cfe({ value="---", label="File date" })
+ if fs.is_file(file) then
+ local filedetails = fs.stat(file)
+ filecontent.value = fs.read_file(file)
+ filesize.value = filedetails.size
+ mtime.value = filedetails.mtime
+ else
+ filename.errtxt = "File not found"
+ end
+ return cfe({ type="group", value={filename=filename, filecontent=filecontent, filesize=filesize, mtime=mtime}, label="Config file details" })
+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
+ 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
end
end
- return serverlist, serverdetails
+ return success, domain
end
+
-- ################################################################################
-- PUBLIC FUNCTIONS
-function startstop_service ( self, action )
- local cmd = action.value
- local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, cmd)
- action.descr=cmdmessage
- action.errtxt=cmderror
- return cmdresult,action
+function startstop_service(action)
+ -- action is validated in daemoncontrol
+ local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, action)
+ return cfe({ type="boolean", value=cmdresult, descr=cmdmessage, errtxt=cmderror, label="Start/Stop result" })
end
function getstatus()
local status = {}
- local config = getconfig()
+
local value, errtxt = processinfo.package_version(packagename)
- status.version = cfe({ name = "version",
+ status.version = cfe({
label="Program version",
value=value,
errtxt=errtxt,
})
- status.status = cfe({ name="status",
+ status.status = cfe({
label="Program status",
value=process_status_text(processname),
})
local autostart_sequense, autostart_errtxt = processinfo.process_botsequence(processname)
- status.autostart = cfe({ name="autostart",
+ status.autostart = cfe({
label="Autostart sequence",
value=autostart_sequense,
errtxt=autostart_errtxt,
})
+
+ return cfe({ type="group", value=status, label="DNS Cache Status" })
+end
- status.ip = cfe({ name="ip",
- label="Listening on",
- value=config.IP or "",
- })
+function getconfig()
+ local conf = getopts.getoptsfromfile(configfile, "") or {}
+ local output = {}
+ output.IPSEND = cfe({ value = conf.IPSEND or "", label="IP address for requests",
+ descr="Use 0.0.0.0 for default address" })
+ output.CACHESIZE = cfe({ value=conf.CACHESIZE or "0", label="Cache size" })
+ output.IP = cfe({ value=conf.IP or "", label="IP address to listen on" })
+ output.FORWARDONLY = cfe({ type="boolean", value=(conf.FORWARDONLY and conf.FORWARDONLY ~= ""),
+ label="Forward only", descr="Servers are parent caches, not root servers" })
+ return cfe({ type="group", value=output, label="DNS Cache Config" })
+end
- status.cachesize = cfe({ name="cachesize",
- label="Cache size",
- value=humanreadable(config.CACHESIZE or ""),
- })
+function setconfig(config)
+ local success, config = validateconfig(config)
- local serverlist, serverdetails = list_servers()
- status.servers = cfe({ name="servers",
- label="Configured DNS-servers",
- value=serverlist,
- option=serverdetails,
- })
+ if success then
+ local file = fs.read_file(configfile)
+ getopts.setoptsinfile(file,"","IPSEND",config.value.IPSEND.value)
+ getopts.setoptsinfile(file,"","CACHESIZE",config.value.CACHESIZE.value)
+ getopts.setoptsinfile(file,"","IP",config.value.IP.value)
+ if config.value.IPSEND.value then
+ getopts.setoptsinfile(file,"","FORWARDONLY",config.value.IPSEND.value)
+ else
+ getopts.setoptsinfile(file,"","FORWARDONLY","")
+ end
+ fs.write_file(configfile, file)
+ else
+ config.errtxt = "Failed to set config"
+ end
- return status
+ return config
end
-function get_logfile ()
- local file = {}
- local cmdtxt = "grep ".. processname .. " /var/log/messages"
- local cmd, error = io.popen(cmdtxt ,r)
- local cmdoutput = cmd:read("*a")
- cmd:close()
+function getconfigfile()
+ local config = getfiledetails(configfile)
+ return config
+end
- file["filename"] = cfe({
- name="filename",
- label="File name",
- value=cmdtxt,
- })
+function setconfigfile(modifications)
+ local configcontent = string.gsub(format.dostounix(modifications), "\n*$", "")
+ local config
+ if fs.is_file(configfile) then
+ fs.write_file(configfile, configcontent)
+ config = getfile(configfile)
+ else
+ config = getfile(configfile)
+ config.value.filecontent.value = configcontent
+ config.errtxt = "Failed to set config"
+ end
- file["filecontent"] = cfe({
- type="longtext",
- name="filecontent",
- label="File content",
- value=cmdoutput,
- })
+ return config
+end
+
+function getIPs()
+ local ipdir = baseurl.."ip"
+ local iplist = cfe({ type="list", value={}, label="IPs to listen for" })
+ 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
- return file
+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 getconfig()
- if (fs.is_file(configfile)) then
- return getopts.getoptsfromfile(configfile, "") or {}
+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 {}
+ return domainlist
end
-function get_filedetails(self,num)
- local path
- if (num == "2") then
- path = configfile2
- else
- path = configfile
- end
- local file = {}
- local filedetails = {}
- local config = {}
- local filenameerrtxt
- if (path) and (fs.is_file(path)) then
- filedetails = fs.stat(path)
- config = getconfig(path)
+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
- config = {}
- config.filename = {}
- config["filename"]["errtxt"]="Config file '".. path .. "' is missing!"
+ local f = io.popen("touch "..baseurl.."servers/"..domain.value.domain.value)
+ f:close()
+ domain.descr = "Created domain"
end
+ return domain
+end
- file["filename" .. (num or "")] = cfe({
- name="filename" .. (num or ""),
- label="File name",
- value=path,
- errtxt=filenameerrtxt
- })
- file["filesize" .. (num or "")] = cfe({
- name="filesize" .. (num or ""),
- label="File size",
- value=filedetails.size or 0,
- })
- file["mtime" .. (num or "")] = cfe({
- name="mtime" .. (num or ""),
- label="File date",
- value=filedetails.mtime or "---",
- })
- file["filecontent" .. (num or "")] = cfe({
- type="longtext",
- name="filecontent" .. (num or ""),
- label="File content",
- value=fs.read_file(path),
- })
-
- -- Sum all errors into one cfe
- local sumerrors = ""
- for k,v in pairs(config) do
- if (config[k]) and (config[k]["errtxt"]) and (config[k]["errtxt"] ~= "") then
- sumerrors = sumerrors .. config[k]["errtxt"] .. "\n"
+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 (sumerrors ~= "") then
- file["sumerrors" .. (num or "")] = cfe ({
- name="sumerrors" .. (num or ""),
- label = "Configuration errors",
- errtxt = string.match(sumerrors, "(.-)\n$"),
- })
+ 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 file
+ return cfe({ type="group", value={domain=domain, iplist=iplist} })
end
-function update_filecontent (self, modifications)
- local path = configfile
- local file_result,err = fs.write_file(path, format.dostounix(modifications))
- return file_result
+
+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") )
+ 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