summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--dnscache-config-html.lsp23
-rw-r--r--dnscache-controller.lua181
-rw-r--r--dnscache-createdomain-html.lsp17
-rw-r--r--dnscache-editdomain-html.lsp17
-rw-r--r--dnscache-editips-html.lsp15
-rw-r--r--dnscache-expert-html.lsp72
-rw-r--r--dnscache-listdomains-html.lsp34
-rw-r--r--dnscache-logfile-html.lsp31
-rw-r--r--dnscache-model.lua349
-rw-r--r--dnscache-startstop-html.lsp26
-rw-r--r--dnscache-status-html.lsp44
-rw-r--r--dnscache.menu4
-rw-r--r--dnscache.roles4
13 files changed, 483 insertions, 334 deletions
diff --git a/dnscache-config-html.lsp b/dnscache-config-html.lsp
new file mode 100644
index 0000000..d1e414d
--- /dev/null
+++ b/dnscache-config-html.lsp
@@ -0,0 +1,23 @@
+<? local form, viewlibrary = ...
+require("viewfunctions")
+?>
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
+--]]
+?>
+
+<? if viewlibrary and viewlibrary.dispatch_component then
+ viewlibrary.dispatch_component("status")
+end ?>
+
+<H1>Config</H1>
+<?
+ displayform(form)
+?>
+
+<? if viewlibrary and viewlibrary.dispatch_component then
+ viewlibrary.dispatch_component("startstop")
+end ?>
diff --git a/dnscache-controller.lua b/dnscache-controller.lua
index 0cc4d92..d50fb63 100644
--- a/dnscache-controller.lua
+++ b/dnscache-controller.lua
@@ -3,115 +3,108 @@ module(..., package.seeall)
-- Load libraries
require("format")
--- Set variables
-local newrecordtxt = "[New]"
-
--- ################################################################################
--- LOCAL FUNCTIONS
-
-local function displaycmdmanagement(pidofstatus)
- -- Add a management buttons
- local management = {}
- management.start = cfe({ name="cmdmanagement",
- label="Program control-panel",
- value="Start",
- type="submit",
- })
- management.stop = cfe({ name="cmdmanagement",
- label="Program control-panel",
- value="Stop",
- type="submit",
- })
- management.restart = cfe({ name="cmdmanagement",
- label="Program control-panel",
- value="Restart",
- type="submit",
- })
- -- next CFE can be used to present the result of the previous action
- management.actionresult = cfe({ name="actionresult",
- label="Previous action result",
- })
-
- -- Disable management buttons based on if the process is running or not
- if (pidofstatus) then
- management.start.disabled = "yes"
- else
- management.stop.disabled = "yes"
- management.restart.disabled = "yes"
+local function handle_form(getFunction, setFunction, clientdata, option, label, descr)
+ local form = getFunction()
+
+ if clientdata[option] then
+ form.errtxt = nil
+ for name,value in pairs(form.value) do
+ value.errtxt = nil
+ if value.type == "boolean" then
+ value.value = (clientdata[name] ~= nil)
+ elseif value.type == "list" then
+ value.value = {}
+ if clientdata[name] and clientdata[name] ~= "" then
+ for ip in string.gmatch(clientdata[name].."\n", "%s*(%S[^\n]*%S)%s*\n") do
+ table.insert(value.value, ip)
+ end
+ end
+ else
+ value.value = clientdata[name] or value.value
+ end
+ end
+ form = setFunction(form)
+ if not form.errtxt then
+ form.descr = descr
+ end
end
- return management
-end
+ form.type = "form"
+ form.option = option
+ form.label = label
--- ################################################################################
--- PUBLIC FUNCTIONS
+ return form
+end
default_action = "status"
function status(self)
- return { status=self.model.getstatus() }
+ return self.model.getstatus()
end
-function expert(self)
- local modifications = self.clientdata.filecontent or ""
- if ( self.clientdata.cmdsave ) then
- modifications = self.model:update_filecontent(modifications)
+function startstop(self)
+ local result
+ if self.clientdata.action then
+ result = self.model.startstop_service(self.clientdata.action)
+ self.sessiondata.dnscachestartstopresult = result
+ self.redirect_to_referrer(self)
end
- local url = self.conf.script .. self.conf.prefix .. self.conf.controller
-
- -- Start/Stop/Restart process
- local cmdmanagement, actionresult
- if ( self.clientdata.cmdmanagement) then
- cmdmanagement = cfe({
- name="cmdmanagement",
- label="Previous action result",
- action=cfe({
- name="cmdmanagement",
- value=string.lower(self.clientdata.cmdmanagement), -- This row contains start/stop/restart (one of these commands)
- }),
- })
- actionresult, cmdmanagement = self.model:startstop_service( cmdmanagement.action )
+
+ local status = self.model.getstatus()
+ status = status.value.status
+ if self.sessiondata.dnscachestartstopresult then
+ result = self.sessiondata.dnscachestartstopresult
+ self.sessiondata.dnscachestartstopresult = nil
end
- local status=self.model.getstatus()
- local file = self.model:get_filedetails()
-
- -- Add buttons
- file.cmdsave = cfe ({
- name="cmdsave",
- label="Apply settings",
- value="Apply",
- type="submit",
- })
- if (self.clientdata.cmdsave) then
- file.cmdsave.descr="* Changes has been saved!"
- end
-
- -- Management buttons (Hide/show buttons
- local pidofstatus
- if (string.lower(status.status.value) == "enabled" ) then pidofstatus = true end
- management = displaycmdmanagement(pidofstatus)
- if (actionresult) then
- management.actionresult.descr=cmdmanagement.descr
- management.actionresult.errtxt=cmdmanagement.errtxt
+ return cfe({ type="group", value={status=status, result=result} })
+end
+
+function config(self)
+ return handle_form(self.model.getconfig, self.model.setconfig, self.clientdata, "Save", "Edit Config", "Configuration Set")
+end
+
+function expert(self)
+ local filedetails
+ if self.clientdata.Save then
+ filedetails = self.model.setconfigfile(self.clientdata.filecontent)
+ if not filedetails.errtxt then
+ filedetails.descr = "Config file set"
+ end
+ else
+ filedetails = self.model.getconfigfile()
end
-
- return ( {
- status = status,
- file = file,
- modifications = modifications,
- management = management,
- url = url, } )
+
+ filedetails.type = "form"
+ filedetails.option = "Save"
+ filedetails.label = "Set config file"
+
+ return filedetails
+end
+
+function editips(self)
+ return handle_form(self.model.getIPs, self.model.setIPs, self.clientdata, "Save", "Edit IP List", "IP List Set")
end
-function logfile(self)
+function listdomains(self)
+ return self.model.getDomains()
+end
- local status=self.model.getstatus()
- local logfile = self.model:get_logfile()
+function createdomain(self)
+ local cmdresult = handle_form(self.model.getNewDomain, self.model.setNewDomain, self.clientdata, "Create", "Create new domain", "New domain created")
+ if cmdresult.descr then
+ redirect_to_referrer(self)
+ end
+ return cmdresult
+end
+
+function editdomain(self)
+ return handle_form(function(form) return self.model.getDomain(self.clientdata.domain) end,
+ self.model.setDomain, self.clientdata, "Save", "Edit domain entry", "Domain saved")
+end
- return ({
- status = status,
- logfile = logfile,
- url = url,
- })
+function deletedomain(self)
+ local cmdresult = self.model.deleteDomain(self.clientdata.domain)
+ redirect_to_referrer(self)
+ return cmdresult
end
diff --git a/dnscache-createdomain-html.lsp b/dnscache-createdomain-html.lsp
new file mode 100644
index 0000000..4347fc0
--- /dev/null
+++ b/dnscache-createdomain-html.lsp
@@ -0,0 +1,17 @@
+<? local form, viewlibrary = ...
+require("viewfunctions")
+?>
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
+--]]
+?>
+
+<H1><?= form.label ?></H1>
+<?
+ form.action = "createdomain"
+ local order = { }
+ displayform(form, order)
+?>
diff --git a/dnscache-editdomain-html.lsp b/dnscache-editdomain-html.lsp
new file mode 100644
index 0000000..34ba902
--- /dev/null
+++ b/dnscache-editdomain-html.lsp
@@ -0,0 +1,17 @@
+<? local form, viewlibrary = ...
+require("viewfunctions")
+?>
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
+--]]
+?>
+
+<H1><?= form.label ?></H1>
+<?
+ form.value.domain.contenteditable = false
+ local order = { "domain", "iplist" }
+ displayform(form, order)
+?>
diff --git a/dnscache-editips-html.lsp b/dnscache-editips-html.lsp
new file mode 100644
index 0000000..b88e2c4
--- /dev/null
+++ b/dnscache-editips-html.lsp
@@ -0,0 +1,15 @@
+<? local form, viewlibrary = ...
+require("viewfunctions")
+?>
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
+--]]
+?>
+
+<H1><?= form.label ?></H1>
+<?
+ displayform(form)
+?>
diff --git a/dnscache-expert-html.lsp b/dnscache-expert-html.lsp
index 4f77e5e..c4ad955 100644
--- a/dnscache-expert-html.lsp
+++ b/dnscache-expert-html.lsp
@@ -1,6 +1,5 @@
-<? local form = ...
-require("viewfunctions")
-?>
+<? local form, viewlibrary = ... ?>
+<? require("viewfunctions") ?>
<?
--[[ DEBUG INFORMATION
io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
@@ -9,50 +8,43 @@ io.write("</span>")
--]]
?>
-<H1>SYSTEM INFO</H1>
-<DL>
-<?
-local myform = form.status
-local tags = { "status", "version", "autostart", }
-displayinfo(myform,tags,"viewonly")
-?>
-</DL>
+<? ---[[ ?>
+<? if viewlibrary and viewlibrary.dispatch_component then
+ viewlibrary.dispatch_component("status")
+end ?>
+<? --]] ?>
-<form name="myform" action="" method="POST">
-<h1>CONFIGURATION</h1>
-<H2>Expert config</H2>
-<h3>File details</h3>
+<H1>Configuration</H1>
+<H2>Expert Configuration</H2>
+<H3>File Details</H3>
<DL>
<?
-local myform = form.file
-local tags = { "filename", "filesize", "mtime", "sumerrors", }
-displayinfo(myform,tags,"viewonly")
+displayitem(form.value.filename)
+displayitem(form.value.filesize)
+displayitem(form.value.mtime)
?>
</DL>
-<H3>FILE CONTENT</H3>
-<?
-local myform = form.file
-io.write(html.form[myform.filecontent.type](myform.filecontent))
-?>
+<H3>File Content</H3>
+<? if form.descr then ?><P CLASS='descr'><?= string.gsub(form.descr, "\n", "<BR>") ?></P><? end ?>
+<? if form.errtxt then ?><P CLASS='error'><?= string.gsub(form.errtxt, "\n", "<BR>") ?></P><? end ?>
+<form action="" method="POST">
+<textarea name="filecontent">
+<?= form.value.filecontent.value ?>
+</textarea>
+<? if form.value.filecontent.errtxt then ?><P CLASS='error'><?= string.gsub(form.value.filecontent.errtxt, "\n", "<BR>") ?></P><? end ?>
-<H2>SAVE AND APPLY ABOVE SETTINGS</H2>
-<DL>
-<?
-local tags = { "cmdsave", }
-displayinfo(myform,tags)
-?>
-</DL>
+<DL><DT></DT><DD><input class="submit" type="submit" name="<?= form.option ?>" value="Save"></DD></DL>
+</form>
+
+<? if viewlibrary and viewlibrary.dispatch_component then
+ viewlibrary.dispatch_component("startstop")
+end ?>
<?
--- Management buttons
-local myform = form.management
-local tags = { "start", "stop", "restart" }
-if (myform) then
- io.write("<H1>MANAGEMENT</H1>\n<DL>")
- displaymanagement(myform,tags)
- io.write("</DL>")
-end
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
+--]]
?>
-</form>
-
diff --git a/dnscache-listdomains-html.lsp b/dnscache-listdomains-html.lsp
new file mode 100644
index 0000000..9c7ba20
--- /dev/null
+++ b/dnscache-listdomains-html.lsp
@@ -0,0 +1,34 @@
+<? local data, viewlibrary = ...
+require("viewfunctions")
+?>
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(data))
+io.write("</span>")
+--]]
+?>
+
+<h1>Configuration</h1>
+<h2>Edit/View DNS server entries</h2>
+<TABLE>
+ <TR style="background:#eee;font-weight:bold;">
+ <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD>
+ <TD style="white-space:nowrap;text-align:left;" class="header">Domain</TD>
+ </TR>
+<? for i,domain in ipairs(data.value) do ?>
+ <TR>
+ <TD style="padding-right:20px;white-space:nowrap;">
+ <? io.write(html.link{value = "editdomain?domain=" .. domain, label="Edit " }) ?>
+ <? if domain ~= "@" then
+ io.write(html.link{value = "deletedomain?domain=" .. domain, label="Delete " })
+ end ?>
+ </TD>
+ <TD style="white-space:nowrap;" width="90%"><?= domain ?></TD>
+ </TR>
+<? end ?>
+</TABLE>
+
+<? if viewlibrary and viewlibrary.dispatch_component then
+ viewlibrary.dispatch_component("createdomain")
+end ?>
diff --git a/dnscache-logfile-html.lsp b/dnscache-logfile-html.lsp
deleted file mode 100644
index aa0b6e5..0000000
--- a/dnscache-logfile-html.lsp
+++ /dev/null
@@ -1,31 +0,0 @@
-<? local form = ... ?>
-<?
-require("viewfunctions")
-?>
-
-<H1>SYSTEM INFO</H1>
-<DL>
-<?
-local myform = form.status
-local tags = { "status", "version", "autostart", }
-displayinfo(myform,tags,"viewonly")
-?>
-</DL>
-
-<form name="myform" action="" method="POST">
-<h1>LOGFILE</h1>
-<h2>Details</h2>
-<DL>
-<?
-local myform = form.logfile
-local tags = { "filename", "filesize", "mtime", "sumerrors", }
-displayinfo(myform,tags,"viewonly")
-?>
-</DL>
-
-<H3>FILE CONTENT</H3>
-<?
-io.write(html.form[myform.filecontent.type](myform.filecontent))
-?>
-
-</form>
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
diff --git a/dnscache-startstop-html.lsp b/dnscache-startstop-html.lsp
new file mode 100644
index 0000000..f963d3b
--- /dev/null
+++ b/dnscache-startstop-html.lsp
@@ -0,0 +1,26 @@
+<? local data = ... ?>
+<? --[[
+io.write(html.cfe_unpack(data))
+--]] ?>
+
+<H1>Management</H1>
+<DL>
+<form action="startstop" method="POST">
+<DT>Program control-panel</DT>
+<DD>
+<input class="submit" type="submit" name="action" value="Start" <? if data.value.status.value== "Enabled" then io.write("disabled") end ?>>
+<input class="submit" type="submit" name="action" value="Stop" <? if data.value.status.value== "Disabled" then io.write("disabled") end ?>>
+<input class="submit" type="submit" name="action" value="Restart" <? if data.value.status.value== "Disabled" then io.write("disabled") end ?>>
+</DD>
+</form>
+
+<? if data.value.result then ?>
+<DT>Previous action result</DT>
+<DD>
+<? if data.value.result.descr then ?>
+<P CLASS='descr'><?= string.gsub(data.value.result.descr, "\n", "<BR>") ?></P>
+<? end if data.value.result.errtxt then ?>
+<P CLASS='error'><?= string.gsub(data.value.result.errtxt, "\n", "<BR>") ?></P>
+<? end end ?>
+</DD>
+</DL>
diff --git a/dnscache-status-html.lsp b/dnscache-status-html.lsp
index 40e4ee4..05b4a7a 100644
--- a/dnscache-status-html.lsp
+++ b/dnscache-status-html.lsp
@@ -1,49 +1,19 @@
-<? local form = ...
+<? local data = ...
require("viewfunctions")
?>
<?
--[[ DEBUG INFORMATION
io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(form))
+io.write(html.cfe_unpack(data))
io.write("</span>")
--]]
?>
-<H1>SYSTEM INFO</H1>
+<H1>System Info</H1>
<DL>
-<?
-local myform = form.status
-local tags = { "status", "version", "autostart", }
-displayinfo(myform,tags,"viewonly")
-?>
-</DL>
-
-<H2>PROGRAM SPECIFIC OPTIONS/INFORMATION</H2>
-<DL>
-<?
-local myform = form.status
-local tags = { "ip", "cachesize", }
-displayinfo(myform,tags,"viewonly")
-?>
-
-<?
-local myform = form.status.servers
-io.write("\t<DT")
-if (myform.errtxt) then io.write(" class='error'") end
-io.write(">" .. myform.label .. "</DT>\n")
-io.write("\t\t<DD>\n")
-for k,v in pairs(myform.value or {}) do
- io.write("\t\t\t<TABLE STYLE='margin-bottom:10px;'>")
- io.write("\n\t\t\t<TR><TD STYLE='font-weight:bold;border:none;'><IMG SRC='/skins/static/tango/16x16/status/network-idle.png' width='16' height='16' alt> " .. v .. "</TD><TD STYLE='border:none;'></TD></TR>\n")
- for k1,v1 in pairs(myform.option[v]) do
- io.write("\n\t\t\t<TR STYLE='padding-bottom:10px;'><TD WIDTH='150px' STYLE='padding-left:30px;border:none;'>"..v1)
- end
-
- io.write("\t\t\t</TABLE>")
-end
-io.write("\t\t</DD>\n")
+<?
+displayitem(data.value.status)
+displayitem(data.value.version)
+displayitem(data.value.autostart)
?>
-
-
</DL>
-
diff --git a/dnscache.menu b/dnscache.menu
index c8a0d32..698225d 100644
--- a/dnscache.menu
+++ b/dnscache.menu
@@ -1,5 +1,7 @@
#CAT GROUP/DESC TAB ACTION
Networking 11DNScache Status status
+Networking 11DNScache Config config
+Networking 11DNScache IPs editips
+Networking 11DNScache DNS_Server_Entries listdomains
Networking 11DNScache Expert expert
-Networking 11DNScache Logfile logfile
diff --git a/dnscache.roles b/dnscache.roles
index 74c0431..a4f82fc 100644
--- a/dnscache.roles
+++ b/dnscache.roles
@@ -1,2 +1,2 @@
-READ=dnscache:status,dnscache:logfile
-UPDATE=dnscache:expert
+READ=dnscache:status
+UPDATE=dnscache:config,dnscache:expert,dnscache:startstop,dnscache:editips,dnscache:listdomains,dnscache:createdomain,dnscache:editdomain,dnscache:deletedomain