summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Havela <mika.havela@gmail.com>2008-02-29 15:52:45 +0000
committerMika Havela <mika.havela@gmail.com>2008-02-29 15:52:45 +0000
commitfffd98587d8467dfe8254689e43383031ca42b66 (patch)
tree95c172315175ceceb3cd27410450cda7341d0e5f
parentae2b0e0d008d64568c91a578a6090dd44860e2ae (diff)
downloadacf-openntpd-fffd98587d8467dfe8254689e43383031ca42b66.tar.bz2
acf-openntpd-fffd98587d8467dfe8254689e43383031ca42b66.tar.xz
Changed so that everything uses acf instead.
Now every keypress reports back status for previous action. Information is presented next to the button recently pressed. git-svn-id: svn://svn.alpinelinux.org/acf/openntpd/trunk@782 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--openntpd-config-html.lsp190
-rw-r--r--openntpd-controller.lua363
-rw-r--r--openntpd-expert-html.lsp136
-rw-r--r--openntpd-logfile-html.lsp111
-rw-r--r--openntpd-model.lua320
-rw-r--r--openntpd-status-html.lsp74
-rw-r--r--openntpd.menu8
7 files changed, 923 insertions, 279 deletions
diff --git a/openntpd-config-html.lsp b/openntpd-config-html.lsp
index dd330a7..88450e7 100644
--- a/openntpd-config-html.lsp
+++ b/openntpd-config-html.lsp
@@ -1,109 +1,121 @@
-<? local view = ... ?>
+<? local form = ... ?>
-<h1>SYSTEM INFO</h1>
+<?
+--[[ 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>")
+--]]
+?>
-<dl>
-<dt>Program status</dt>
-<dd><? if (view.status.enabled) then io.write('Enabled') else io.write('Disabled') end ?></dd>
+<?
+function displayinfo(myform,tags,viewtype)
+ for k,v in pairs(tags) do
+ if (myform[v]) and (myform[v]["value"]) then
+ local val = myform[v]
+ io.write("\n\t<DT")
+ if (#val.errtxt > 0) then
+ val.class = "error"
+ io.write(" class='error'")
+ end
+ io.write(">" .. val.label .. "</DT>")
+ io.write("\n\t\t<DD>")
+ if (viewtype == "viewonly") then
+ io.write(val.value)
+ elseif (val.type == "radio") and (type(val.option) == "table") and (#val.option > 0) then
+ io.write("<span style='display:inline' class='" .. ( val.class or "") .. "'>")
+ for k1,v1 in pairs(val.option) do
+ io.write(tostring(v1.label) .. ":")
+ io.write("<input style='margin-right:20px;margin-left:5px;' type='radio' class='" .. ( val.class or "") .. "' name='" .. val.name .. "'")
+ if (tostring(val.value) == tostring(v1.value)) then io.write(" checked='yes'") end
+ io.write(" value='" .. v1.value .. "'>")
+ end
+ io.write("</input></span>")
+ else
+ io.write(html.form[val.type](val))
+ end
+ if (val.descr) and (#val.descr > 0) then io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>") end
+ if (#val.errtxt > 0) then io.write("\n\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
+ io.write("\n\t\t</DD>\n")
+ end
+ end
+end
+?>
-<dt>Program version</dt>
-<dd><?= view.status.version ?></dd>
-</dl>
+<H1>SYSTEM INFO</H1>
+<DL>
+<?
+local myform = form.status
+local tags = { "status", "version", }
+displayinfo(myform,tags,"viewonly")
+?>
+</DL>
-<h1>CONFIGURATION</h1>
+<h1>CONFIGURATION</h1>
<H2>Advanced config</H2>
<H3>General settings</H3>
-
+<DL>
<form name="cmd" action="" method="POST">
+<?
+local myform = form.config
+local tags = { "setstimeonstartup", "cmdsavesetstimeonstartup", }
+displayinfo(myform,tags)
+?>
+</DL>
-<dl>
-<dt>Set time immediately at startup</dt>
-<dd><input type="checkbox" name="settings_startup" <? if (view.status.setstimeonstartup) then io.write("checked") end ?>></dd>
-
-<dt>Save the above settings</dt>
-<dd><input name="settings_cmd" class="submit" type="submit" value="Save"> (see above)
-</dd>
-
-</dl>
-</form>
<h3>'SET TIME' OPTIONS</h3>
-
-<form name="cmd" action="" method="POST">
-
-<dl>
-<dt>Timeserver hosts...</dt>
-<dd>
-<select name="hosts_list" size="3">
-<? if (view.config.variables.servers) then
-for i = 1, table.maxn(view.config.variables.servers) do ?>
- <option value="servers <? io.write(view.config.variables.servers[i].value) ?>"><? io.write(view.config.variables.servers[i].value) ?> (pool)</option>
-<? end end ?>
-<? if (view.config.variables.server) then
-for i = 1, table.maxn(view.config.variables.server) do ?>
- <option value="server <? io.write(view.config.variables.server[i].value) ?>"><? io.write(view.config.variables.server[i].value) ?></option>
-<? end end ?>
-</select><BR>
-In most cases you could use <i><b>pool.ntp.org</b></i> or <i><b>[countryname].pool.ntp.org</i></b> (if listed in <i><b>http://www.pool.ntp.org/</b></i>).
-<? if (view.errors.hosts_list) then io.write("<p class=error>"..view.errors.hosts_list.."</p>") end ?></dd>
-
-<dt>Delete selected host</dt>
-<dd><input name="hosts_cmd" class="submit" type="submit" value="Delete"> (see above)</dd>
-
-<dt <? if (view.errors.hosts_add) then io.write("class=error") end ?>>Host to add</dt>
-<dd><input type="text" name="hosts_add" class="text" value="<?= view.errors.hosts_add_orgvalue or "" ?>"><? if (view.errors.hosts_add) then io.write("<p class=error>"..view.errors.hosts_add.."</p>") end ?></dd>
-
-<dt <? if (view.errors.hosts_type) then io.write("class=error") end ?>>Type of above server</dt>
-<dd><span style="display:inline">Single server:<input type="radio" name="hosts_type" value="server"> Server pool:<input type="radio" name="hosts_type" value="servers"></span><? if (view.errors.hosts_type) then io.write("<p class=error>"..view.errors.hosts_type.."</p>") end ?></dd>
-
-<dt>Add new host</dt>
-<dd><input name="hosts_cmd" class="submit"type="submit" value="Add"></dd>
-</dl>
+<DL>
+<?
+local myform = form.config
+local tags = { "hosts_list", "hosts_cmd_delete", "hosts_add", "hosts_type", "hosts_cmd_add", }
+displayinfo(myform,tags)
+?>
</form>
+</DL>
-<h3>'PRESENT TIME' OPTIONS (ACT AS TIME SERVER)</h3>
+<h3>'PRESENT TIME' OPTIONS (ACT AS TIME SERVER)</h3>
<form name="cmd" action="" method="POST">
-<dl>
-<dt>Listen on address...</dt>
-<dd>
-<select name="listen_list" size="3">
-<? if (view.config.variables.listen) then
-for i = 1, table.maxn(view.config.variables.listen) do ?>
- <option value="listen on <? io.write(view.config.variables.listen[i].value) ?>"><? io.write(view.config.variables.listen[i].value) ?></option>
-<? end end ?>
-</select><BR>Empty list = Listening (acting as server) is disabled<br>"*" = Listen on all local addresses
-<? if (view.errors.listen_list) then io.write("<p class=error>"..view.errors.listen_list.."</p>") end ?>
-</dd>
-
-<dt>Delete selected address</dt>
-<dd><input name="listen_cmd" type="submit" class="submit" value="Delete"> (see above)</dd>
-
-<dt>Add new listen address</dt>
-<dd><input name="listen_add" type="text" class="text" value=""> <input name="listen_cmd" type="submit" class="submit" value="Add"><? if (view.errors.listen_add) then io.write("<p class=error>"..view.errors.listen_add.."</p>") end ?></dd>
-</dl>
-</form>
-
-<H1>MANAGEMENT</H1>
-
-<dl>
-<dt>Program controll-panel</dt>
-<dd><form name="cmd" action="" method="POST">
-<input type=submit class="submit" name="cmd" value="start">
-<input type=submit class="submit" name="cmd" value="stop">
-<input type=submit class="submit" name="cmd" value="restart">
-</form></dd>
-
-<? if (view.startstop) and (view.startstop.cmdresult) then ?>
-<dt>Previous action result</dt>
-<dd><pre><?= view.startstop.cmdresult?></pre></dd>
-<? end ?>
-</dl>
+<DL>
+<?
+local myform = form.config
+local tags = { "listen_list", "listen_cmd_delete", "listen_add", "listen_cmd_add", }
+displayinfo(myform,tags)
+?>
+</DL>
+
+
+<? -- MANAGEMENT BUTTONS
+local cmdform = form.management
+local cmdresult = form.cmdmanagement
+local tags = { "start", "stop", "restart" }
+if (cmdform) and (cmdform[tags[1]]) then
+
+ io.write('<form name="management" action="" method="POST">')
+ io.write('<H1>MANAGEMENT</H1>')
+ io.write('<dl>')
+ io.write('<dt>' .. cmdform[tags[1]]["label"] .. '</dt>')
+ io.write('<dd>')
+ for k,v in pairs(tags) do
+ if (cmdform[v]) then
+ io.write(html.form[cmdform[v].type](cmdform[v]))
+ end
+ end
+ io.write('</dd>')
+
+ if (cmdresult) and (cmdresult.action) and (#cmdresult.action.descr > 0) then
+ io.write('<dt>' .. cmdresult.label .. '</dt>')
+ io.write('<dd><pre>' .. cmdresult.action.descr .. '</pre></dd>')
+ end
+ io.write('</dl></form>')
+end ?>
<?
--[[ DEBUG INFORMATION
-require("debugs")
-io.write(debugs.variables(view))
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
--]]
?>
diff --git a/openntpd-controller.lua b/openntpd-controller.lua
index 7031263..22fb89f 100644
--- a/openntpd-controller.lua
+++ b/openntpd-controller.lua
@@ -5,6 +5,8 @@ module (..., package.seeall)
-- We use the self.conf table because it already has prefix,controller,etc
-- The redir code is defined in the application error handler (acf-controller)
require("posix")
+require("validator")
+
local list_redir = function (self)
self.conf.action = "read"
self.conf.type = "redir"
@@ -18,28 +20,165 @@ mvc.on_load = function(self, parent)
end
end
+local function getstatus(self)
+ local status = self.model.getstatus()
+ if (#status.status.value > 0) then
+ status.status.value = "Enabled"
+ else
+ status.status.value = "Disabled"
+ end
+ return status
+end
+
+local function displaycmdmanagement(disablestart,disablestop,disablerestart)
+ -- 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",
+ })
+
+ -- Disable management buttons based on if the process is running or not
+ if (disablestart) then management.start.disabled = "yes" end
+ if (disablestop) then management.stop.disabled = "yes" end
+ if (disablerestart) then management.restart.disabled = "yes" end
+
+ return management
+end
+
+local function displaycmdsave(self)
+ -- Add a cmd button to the view
+ local cmdsave = cfe({ name="cmdsave",
+ label="Save/Apply above settings",
+ value="Save",
+ type="submit",
+ })
+ return cmdsave
+end
config = function (self)
- local cmd = self.clientdata.cmd
local errors = {}
local modify_opts = nil
- local url = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller
- local hosts_cmd = tostring(self.clientdata.hosts_cmd)
- local hosts_cmd = string.lower(hosts_cmd)
- local listen_cmd = tostring(self.clientdata.listen_cmd)
- local listen_cmd = string.lower(listen_cmd)
- local settings_cmd = tostring(self.clientdata.settings_cmd)
- local settings_cmd = string.lower(settings_cmd)
+ local cmdsavereply = {}
+ local cmdsaveresult = {}
+ -- Start/Stop/Restart process
+ local cmdmanagement
+ 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)
+ }),
+ })
+ local actionresult, cmdmanagement = self.model:startstop_service( cmdmanagement.action )
+ end
+
+ if (self.clientdata.cmdsavesetstimeonstartup) then
+ if (self.clientdata.setstimeonstartup) then
+ modify_opts = self.model:modify_opts("add", "/etc/conf.d/ntpd", "NTPD_OPTS", "-s")
+ else
+ modify_opts = self.model:modify_opts("remove", "/etc/conf.d/ntpd", "NTPD_OPTS", "-s")
+ end
+ end
+
+ if ( self.clientdata.hosts_cmd_delete) then
+ local variables="hosts_cmd_delete"
+ for var in string.gmatch(variables, "%S+") do
+ -- Send nil instead of "" causes the parameter to be removed/deleted/empty/unset the variable in the config-file
+-- if (self.clientdata[var] == "") then self.clientdata[var] = nil end
+ cmdsaveresult[var], cmdsavereply[var] = self.model:modify_config( "delete",
+ "server%S?" ,
+ string.match(self.clientdata["hosts_list"], "^%s*(%S*)") )
+ end
+ end
+
+ if ( self.clientdata.listen_cmd_delete) then
+ local variables="listen_cmd_delete"
+ for var in string.gmatch(variables, "%S+") do
+ -- Send nil instead of "" causes the parameter to be removed/deleted/empty/unset the variable in the config-file
+-- if (self.clientdata[var] == "") then self.clientdata[var] = nil end
+ cmdsaveresult[var], cmdsavereply[var] = self.model:modify_config( "delete",
+ "listen on" ,
+ string.match(self.clientdata["listen_list"], "^%s*(%S*)") )
+ end
+ end
+
+ if ( self.clientdata.hosts_cmd_add) then
+ local variables="hosts_cmd_add"
+ for var in string.gmatch(variables, "%S+") do
+ local freetocommit
+ -- Do some checking before executing the command
+ if not (self.clientdata["hosts_type"]) then
+ cmdsavereply["hosts_type"] = cfe ({
+ errtxt="You need chose type of host to add!",
+ })
+ cmdsavereply["hosts_add"] = cfe ({
+ value=self.clientdata["hosts_add"],
+ })
+ end
+ if (#self.clientdata["hosts_add"] == 0) then
+ cmdsavereply["hosts_add"] = cfe ({ errtxt="You need to add a valid hostname/IP!", })
+ end
+
+ if not ( cmdsavereply["hosts_type"] and cmdsavereply["hosts_type"]["errtxt"]) and not
+ (cmdsavereply["hosts_add"] and cmdsavereply["hosts_add"]["errtxt"]) then
+ -- Send nil instead of "" causes the parameter to be removed/deleted/empty/unset the variable in the config-file
+-- if (self.clientdata[var] == "") then self.clientdata[var] = nil end
+ cmdsaveresult[var], cmdsavereply[var] = self.model:modify_config( "add",
+ self.clientdata["hosts_type"] ,
+ self.clientdata["hosts_add"] )
+ end
+ end
+ end
+
+ if ( self.clientdata.listen_cmd_add) then
+ local variables="listen_cmd_add"
+ for var in string.gmatch(variables, "%S+") do
+ local freetocommit
+ -- Do some checking before executing the command
+ if (#self.clientdata["listen_add"] == 0) then
+ cmdsavereply["listen_add"] = cfe ({ errtxt="You need to add a valid hostname/IP!", })
+ end
+
+ if not ( cmdsavereply["listen_add"] and cmdsavereply["listen_add"]["errtxt"]) then
+ -- Send nil instead of "" causes the parameter to be removed/deleted/empty/unset the variable in the config-file
+-- if (self.clientdata[var] == "") then self.clientdata[var] = nil end
+ cmdsaveresult[var], cmdsavereply[var] = self.model:modify_config( "add",
+ "listen on",
+ self.clientdata["listen_add"] )
+ end
+ end
+ end
+
+
+--[[
-- SECTION WHERE YOU SAVE NEW SETTINGS
- if ( hosts_cmd == "delete") then
+ if ( self.clientdata.hosts_cmd_delete ) then
if not (self.clientdata.hosts_list) then
errors["hosts_list"]="You need to choose something in the list to delete"
end
+
if (self.clientdata.hosts_list) then
- modify_opts = self.model:modify_config(hosts_cmd, nil, self.clientdata.hosts_list)
+ modify_opts = self.model:modify_config(string.lower(tostring(self.clientdata.hosts_cmd)), nil, self.clientdata.hosts_list)
end
- elseif (hosts_cmd == "add") then
+
+
+
+ if (string.lower(tostring(self.clientdata.hosts_cmd)) == "add") then
if (self.clientdata.hosts_add == "") then
errors["hosts_add"]="You need to enter a server/IP"
end
@@ -48,70 +187,214 @@ config = function (self)
errors["hosts_add_orgvalue"] = self.clientdata.hosts_add
end
if (self.clientdata.hosts_add ~= "") and (self.clientdata.hosts_type ~= nil) then
- modify_opts = self.model:modify_config(hosts_cmd, nil, self.clientdata.hosts_type .. " " .. self.clientdata.hosts_add)
+ modify_opts = self.model:modify_config(string.lower(tostring(self.clientdata.hosts_cmd)), nil, self.clientdata.hosts_type .. " " .. self.clientdata.hosts_add)
end
- elseif (listen_cmd == "add") then
+ elseif (string.lower(tostring(self.clientdata.listen_cmd)) == "add") then
if (self.clientdata.listen_add == "") then
errors["listen_add"]="You need to enter what you want to listen at"
end
if (self.clientdata.listen_add ~= "") then
- modify_opts = self.model:modify_config(listen_cmd, nil, "listen on " .. self.clientdata.listen_add)
+ modify_opts = self.model:modify_config(string.lower(tostring(self.clientdata.listen_cmd)), nil, "listen on " .. self.clientdata.listen_add)
end
- elseif (listen_cmd == "delete") then
+ elseif (string.lower(tostring(self.clientdata.listen_cmd)) == "delete") then
if not (self.clientdata.listen_list) then
errors["listen_list"]="You need to choose something in the list to delete"
end
if (self.clientdata.listen_list) then
- modify_opts = self.model:modify_config(listen_cmd, nil, self.clientdata.listen_list)
+ modify_opts = self.model:modify_config(string.lower(tostring(self.clientdata.listen_cmd)), nil, self.clientdata.listen_list)
end
- elseif (settings_cmd == "save") then
- if (self.clientdata.settings_startup) then
- modify_opts = self.model:modify_opts("add", "/etc/conf.d/ntpd", "NTPD_OPTS", "-s")
- else
- modify_opts = self.model:modify_opts("remove", "/etc/conf.d/ntpd", "NTPD_OPTS", "-s")
+--]]
+
+ local url = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller
+ local status = getstatus(self)
+ local config = self.model:getconfig()
+
+ -- Add buttons
+ config.hosts_cmd_delete = cfe({
+ name = "hosts_cmd_delete",
+ label="Delete selected host",
+ value="Delete",
+ type="submit",
+ })
+ config.hosts_cmd_delete.descr="Mark a item in '" .. config.hosts_list.label .. "'-list before pressing [" .. config.hosts_cmd_delete.value .. "]."
+ if (#config.hosts_list.option == 0) then
+ config.hosts_cmd_delete.disabled = "yes"
+ config.hosts_cmd_delete.descr = ""
+ end
+
+ config.listen_cmd_delete = cfe({
+ name = "listen_cmd_delete",
+ label="Delete selected host",
+ value="Delete",
+ type="submit",
+ })
+ config.listen_cmd_delete.descr="Mark a item in '" .. config.listen_list.label .. "'-list before pressing [" .. config.listen_cmd_delete.value .. "]."
+ if (#config.listen_list.option == 0) then
+ config.listen_cmd_delete.disabled = "yes"
+ config.listen_cmd_delete.descr = ""
+ end
+
+ config.hosts_cmd_add = cfe({
+ name = "hosts_cmd_add",
+ label="Add selected host",
+ value="Add",
+ type="submit",
+ })
+ config.hosts_cmd_add.descr="Enter your values in '" .. config.hosts_add.label .. "' and chose '" .. config.hosts_type.label .. "' before pressing [" .. config.hosts_cmd_add.value .. "]."
+
+ config.listen_cmd_add = cfe({
+ name = "listen_cmd_add",
+ label="Add new listen address",
+ value="Add",
+ type="submit",
+ })
+ config.listen_cmd_add.descr="Enter your values in '" .. config.listen_add.label .. "' before pressing [" .. config.listen_cmd_add.value .. "]."
+
+ -- Management buttons
+ local disablestart,disablestop,disablerestart
+ -- Disable management buttons based on if the process is running or not
+ if (string.lower(status.status.value) == "enabled" ) then
+ disablestart = "yes"
+ else
+ disablestop = "yes"
+ end
+ -- Disable management buttons if there exist errors in the config
+ for k,v in pairs(config) do
+ if (config[k]["errtxt"] ~= "") then
+ disablestart = "yes"
+ disablestop = "yes"
+ disablerestart = "yes"
+ break
end
end
+ -- Display management buttons
+ local management = displaycmdmanagement(disablestart,disablestop,disablerestart)
- DEBUGMODEL = modify_opts -- <<< DEBUG INFO >>>
- DEBUGCLIENTDATA = self.clientdata -- <<< DEBUG INFO >>>
- local startstop
- if ( cmd ~= nil ) then
- startstop = self.model:startstop_service( cmd )
+ -- Write out erros and descriptions from previous actions
+ for k,v in pairs(cmdsavereply) do
+ if (config[k]) and (cmdsavereply[k]["errtxt"]) and (#cmdsavereply[k]["errtxt"] > 0) then
+ config[k]["errtxt"] = tostring(cmdsavereply[k]["errtxt"])
+ end
+ if (config[k]) and (cmdsavereply[k]["descr"]) and (#cmdsavereply[k]["descr"] > 0) then
+ config[k]["descr"] = tostring(cmdsavereply[k]["descr"])
+ end
+ if (config[k]) and (cmdsavereply[k]["value"]) and (#cmdsavereply[k]["value"] > 0) then
+ config[k]["value"] = tostring(cmdsavereply[k]["value"])
+ end
end
- return ( {status = self.model:getstatus(),
- config = self.model:getconfig(),
+
+ DEBUGMODEL = modify_opts -- <<< DEBUG INFO >>>
+ return ( {status = status,
+ config = config,
+ management = management,
url = url,
errors = errors,
- startstop = startstop, } )
+ cmdmanagement = cmdmanagement,
+
+ cmdsavereply = cmdsavereply,
+ cmdsaveresult = cmdsaveresult,
+ modify_opts = modify_opts,
+ clientdata = self.clientdata,
+ } )
end
logfile = function (self)
- return ( {status = self.model:getstatus(), logfile = self.model:get_logfile(), url = url } )
+ -- Start/Stop/Restart process
+ local cmdmanagement
+ 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)
+ }),
+ })
+ local actionresult, cmdmanagement = self.model:startstop_service( cmdmanagement.action )
+ end
+
+ local status = getstatus(self)
+ local logfile = self.model:get_logfile()
+
+ -- Management buttons
+ local disablestart,disablestop,disablerestart
+ -- Disable management buttons based on if the process is running or not
+ if (string.lower(status.status.value) == "enabled" ) then
+ disablestart = "yes"
+ else
+ disablestop = "yes"
+ end
+ -- Display management buttons
+ management = displaycmdmanagement(disablestart,disablestop,disablerestart)
+
+ return ({
+ management = management,
+ cmdmanagement = cmdmanagement,
+ status = status,
+ logfile = logfile,
+ url = url,
+ })
end
status = function (self)
local cmd = self.clientdata.cmd
local url = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller
- return ( {status = self.model:getstatus(), url = url } )
+ return ( {status = getstatus(self), url = url } )
end
expert = function (self)
- local modifications = self.clientdata.modifications or ""
- local cmd = self.clientdata.cmd
+ local modifications = self.clientdata.filecontent or ""
+ if ( self.clientdata.cmdsave ) then
+ modifications = self.model:update_filecontent(modifications)
+ end
local url = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller
- if ( modifications ~= "") then
- modifications = self.model:update_filecontent(modifications)
+ -- Start/Stop/Restart process
+ local cmdmanagement
+ 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)
+ }),
+ })
+ local actionresult, cmdmanagement = self.model:startstop_service( cmdmanagement.action )
end
- if ( cmd ~= nil ) then
- startstop = self.model:startstop_service( cmd )
+ local status = getstatus(self)
+ 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
+ local disablestart,disablestop,disablerestart
+ -- Disable management buttons based on if the process is running or not
+ if (string.lower(status.status.value) == "enabled" ) then
+ disablestart = "yes"
+ else
+ disablestop = "yes"
end
+ -- Display management buttons
+ management = displaycmdmanagement(disablestart,disablestop,disablerestart)
- return ( {startstop = startstop,
- status = self.model:getstatus(),
- file = self.model:get_filedetails(),
+ return ( {
+ status = status,
+ file = file,
modifications = modifications,
+ management = management,
+ cmdmanagement = cmdmanagement,
url = url, } )
end
diff --git a/openntpd-expert-html.lsp b/openntpd-expert-html.lsp
index ede8ecc..13825ec 100644
--- a/openntpd-expert-html.lsp
+++ b/openntpd-expert-html.lsp
@@ -1,71 +1,113 @@
-<? local view = ... ?>
+<? local form = ... ?>
<?
--[[ DEBUG INFORMATION
-require("debugs")
-io.write(debugs.variables(view))
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
--]]
?>
+<?
+function displayinfo(myform,tags,viewtype)
+ for k,v in pairs(tags) do
+ if (myform[v]) and (myform[v]["value"]) then
+ local val = myform[v]
+ io.write("\n\t<DT")
+ if (#val.errtxt > 0) then
+ val.class = "error"
+ io.write(" class='error'")
+ end
+ io.write(">" .. val.label .. "</DT>")
+ io.write("\n\t\t<DD>")
+ if (viewtype == "viewonly") then
+ io.write(val.value)
+ elseif (val.type == "radio") and (type(val.option) == "table") and (#val.option > 0) then
+ io.write("<span style='display:inline' class='" .. ( val.class or "") .. "'>")
+ for k1,v1 in pairs(val.option) do
+ io.write(tostring(v1.label) .. ":")
+ io.write("<input style='margin-right:20px;margin-left:5px;' type='radio' class='" .. ( val.class or "") .. "' name='" .. val.name .. "'")
+ if (tostring(val.value) == tostring(v1.value)) then io.write(" checked='yes'") end
+ io.write(" value='" .. v1.value .. "'>")
+ end
+ io.write("</input></span>")
+ else
+ io.write(html.form[val.type](val))
+ end
+ if (val.descr) and (#val.descr > 0) then io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>") end
+ if (#val.errtxt > 0) then io.write("\n\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
+ io.write("\n\t\t</DD>\n")
+ end
+ end
+end
+?>
-<h1>SYSTEM INFO</h1>
-
-<dl>
-<dt>Program status
-<dd><? if (view.status.enabled) then io.write('Enabled') else io.write('Disabled') end ?></dd>
+<H1>SYSTEM INFO</H1>
+<DL>
+<?
+local myform = form.status
+local tags = { "status", "version", }
+displayinfo(myform,tags,"viewonly")
+?>
+</DL>
-<dt>Program version</dt>
-<dd><?= view.status.version ?></dd>
-</dl>
+<form name="myform" action="" method="POST">
<h1>CONFIGURATION</h1>
-
<H2>Expert config</H2>
-
<h3>File details</h3>
-
<DL>
-<dt>File name</dt>
-<dd><?= view.file.details.path ?></dd>
-
-<dt>File size</dt>
-<dd><?= view.file.details.size ?></dd>
-
-<dt>Last modified</dt>
-<dd><?= view.file.details.mtime ?></dd>
+<?
+local myform = form.file
+local tags = { "filename", "filesize", "mtime", "sumerrors", }
+displayinfo(myform,tags,"viewonly")
+?>
</DL>
-<h3>File content</h3>
-
-<form name="myform" action="" method="POST">
-<input name="name" type=hidden value="">
-<textarea name="modifications"><?= view.file.content ?></textarea>
+<H3>FILE CONTENT</H3>
+<?
+local myform = form.file
+io.write(html.form[myform.filecontent.type](myform.filecontent))
+?>
-<H2>Save and apply above settings</H2>
+<H2>SAVE AND APPLY ABOVE SETTINGS</H2>
<DL>
-<DT>Apply settings</DT>
-<DD><input class="submit" type="submit" value="Apply"/></DD>
+<?
+local tags = { "cmdsave", }
+displayinfo(myform,tags)
+?>
</DL>
-</form>
-<H1>MANAGEMENT</H1>
-
-<dl>
-<dt>Program controll-panel</dt>
-<dd><form name="cmd" action="" method="POST">
-<input type=submit class="submit" name="cmd" value="start">
-<input type=submit class="submit" name="cmd" value="stop">
-<input type=submit class="submit" name="cmd" value="restart">
-</form></dd>
+</form>
-<? if (view.startstop) and (view.startstop.cmdresult) then ?>
-<dt>Previous action result</dt>
-<dd><pre><?= view.startstop.cmdresult?></pre></dd>
-<? end ?>
-</dl>
+<? -- MANAGEMENT BUTTONS
+local cmdform = form.management
+local cmdresult = form.cmdmanagement
+local tags = { "start", "stop", "restart" }
+if (cmdform) and (cmdform[tags[1]]) then
+
+ io.write('<form name="management" action="" method="POST">')
+ io.write('<H1>MANAGEMENT</H1>')
+ io.write('<dl>')
+ io.write('<dt>' .. cmdform[tags[1]]["label"] .. '</dt>')
+ io.write('<dd>')
+ for k,v in pairs(tags) do
+ if (cmdform[v]) then
+ io.write(html.form[cmdform[v].type](cmdform[v]))
+ end
+ end
+ io.write('</dd>')
+
+ if (cmdresult) and (cmdresult.action) and (#cmdresult.action.descr > 0) then
+ io.write('<dt>' .. cmdresult.label .. '</dt>')
+ io.write('<dd><pre>' .. cmdresult.action.descr .. '</pre></dd>')
+ end
+ io.write('</dl></form>')
+end ?>
<?
--[[ DEBUG INFORMATION
-require("debugs")
-io.write(debugs.variables(view))
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
--]]
?>
diff --git a/openntpd-logfile-html.lsp b/openntpd-logfile-html.lsp
index 41c7f95..e9bf0e4 100644
--- a/openntpd-logfile-html.lsp
+++ b/openntpd-logfile-html.lsp
@@ -1,33 +1,104 @@
-<? local view = ... ?>
+<? local form = ... ?>
-<h1>SYSTEM INFO</h1>
-
-<dl>
-<dt>Program status
-<dd><? if (view.status.enabled) then io.write('Enabled') else io.write('Disabled') end ?></dd>
-</dl>
+<?
+--[[ 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>")
+--]]
+?>
+<?
+function displayinfo(myform,tags,viewtype)
+ for k,v in pairs(tags) do
+ if (myform[v]) and (myform[v]["value"]) then
+ local val = myform[v]
+ io.write("\n\t<DT")
+ if (#val.errtxt > 0) then
+ val.class = "error"
+ io.write(" class='error'")
+ end
+ io.write(">" .. val.label .. "</DT>")
+ io.write("\n\t\t<DD>")
+ if (viewtype == "viewonly") then
+ io.write(val.value)
+ elseif (val.type == "radio") and (type(val.option) == "table") and (#val.option > 0) then
+ io.write("<span style='display:inline' class='" .. ( val.class or "") .. "'>")
+ for k1,v1 in pairs(val.option) do
+ io.write(tostring(v1.label) .. ":")
+ io.write("<input style='margin-right:20px;margin-left:5px;' type='radio' class='" .. ( val.class or "") .. "' name='" .. val.name .. "'")
+ if (tostring(val.value) == tostring(v1.value)) then io.write(" checked='yes'") end
+ io.write(" value='" .. v1.value .. "'>")
+ end
+ io.write("</input></span>")
+ else
+ io.write(html.form[val.type](val))
+ end
+ if (val.descr) and (#val.descr > 0) then io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>") end
+ if (#val.errtxt > 0) then io.write("\n\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
+ io.write("\n\t\t</DD>\n")
+ end
+ end
+end
+?>
-<dl>
-<dt>Program version</dt>
-<dd><?= view.status.version ?></dd>
-</dl>
+<H1>SYSTEM INFO</H1>
+<DL>
+<?
+local myform = form.status
+local tags = { "status", "version", }
+displayinfo(myform,tags,"viewonly")
+?>
+</DL>
+<? local myform = form.logfile ?>
+<form name="myform" action="" method="POST">
<h1>LOGFILE</h1>
-
<h2>Details</h2>
+<DL>
+<?
+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>
+
+
+<? -- MANAGEMENT BUTTONS
+local cmdform = form.management
+local cmdresult = form.cmdmanagement
+local tags = { "start", "stop", "restart" }
+if (cmdform) and (cmdform[tags[1]]) then
-<dl>
-<dt>Logfile</dt>
-<dd><?= view.logfile.cmd ?></dd>
-</dl>
+ io.write('<form name="management" action="" method="POST">')
+ io.write('<H1>MANAGEMENT</H1>')
+ io.write('<dl>')
+ io.write('<dt>' .. cmdform[tags[1]]["label"] .. '</dt>')
+ io.write('<dd>')
+ for k,v in pairs(tags) do
+ if (cmdform[v]) then
+ io.write(html.form[cmdform[v].type](cmdform[v]))
+ end
+ end
+ io.write('</dd>')
-<h2>Content</h2>
-<textarea name=""><? io.write(view.logfile.value) ?></textarea>
+ if (cmdresult) and (cmdresult.action) and (#cmdresult.action.descr > 0) then
+ io.write('<dt>' .. cmdresult.label .. '</dt>')
+ io.write('<dd><pre>' .. cmdresult.action.descr .. '</pre></dd>')
+ end
+ io.write('</dl></form>')
+end ?>
<?
--[[ DEBUG INFORMATION
-require("debugs")
-io.write(debugs.variables(view))
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(form))
+io.write("</span>")
--]]
?>
diff --git a/openntpd-model.lua b/openntpd-model.lua
index 7a93151..e5d8163 100644
--- a/openntpd-model.lua
+++ b/openntpd-model.lua
@@ -40,13 +40,15 @@ local function config_content( f )
return config
end
-local function get_version ()
- local f,error = io.popen("/sbin/apk_version -v -s openntpd")
- local programversion = f:read("*a")
- f:close()
- return programversion
+local function get_version()
+ local cmd = "/sbin/apk_version -v -s openntpd | cut -d ' ' -f 1"
+ local cmd_output = io.popen( cmd )
+ local cmd_output_result = cmd_output:read("*a") or ""
+ cmd_output:close()
+ return cmd_output_result
end
+
local function last_time_change()
local cmdoutput = {}
local cmd, error = io.popen("cat /var/log/messages | grep ntpd | grep adjusting | tail -1" ,r)
@@ -82,43 +84,106 @@ local function addremove_opts( addremove, file, variable, option )
end
return cmdtxt
end
-local function addremove_config( addremove, file, variable )
- -- Notes on known/unknown bugs: Remove 'server www.test.org' wont work if config has multiple space/tab e.g. 'server www.test.org'
- -- FIXME: Make num-space unsensetive.
- -- FIXME: Can hold multiple rows with same values (when deleting... every equal row is deleted)
- local cmdoutput = nil
+local function addremove_config( addremove, variable, value )
+ local file = configfile
+ local cmdoutput
+ local filecontentarray = fs.read_file_as_array(file)
if (addremove == "delete" ) then
- cmdtxt = "/bin/sed -i '/" .. variable .. "/d' " .. file
- local cmd, error = io.popen ( cmdtxt )
- cmdoutput = cmd:read("*a")
- cmd:close()
+ if not (value) then
+ return false, cfe({
+ name="openntpd.model.addremove_config(delete)",
+ errtxt="You need to choose a 'Timeserver host' to delete!",
+ })
+ end
+
+ local modifyresult
+ for k,v in pairs(filecontentarray) do
+ if (string.find(v,"^%s*" .. variable .. "%s*" .. value .. "%s*$" )) then
+ modifyresult = k
+ break
+ end
+ end
+
+ if (modifyresult) then
+ table.remove(filecontentarray,modifyresult)
+ fs.write_file(file, table.concat(filecontentarray, "\n"))
+
+ return true, cfe({
+ name="openntpd.model.addremove_config(delete)",
+ descr="* Record was successfully deleted!",
+ })
+ end
+
+ -- If nothing happened... then report error!
+ return false, cfe({
+ name="openntpd.model.addremove_config(delete)",
+ errtxt="Couldn't find the record to delete!",
+ })
+
elseif (addremove == "add" ) then
- cmdtxt = "/bin/echo '" .. variable .. "' >> " .. file
- local cmd, error = io.popen ( cmdtxt )
- cmdoutput = cmd:read("*a")
- cmd:close()
- end
- if (cmdoutput) then
- cmdresult = "Config is modified! (" .. cmdtxt .. ")"
+ if not (value) then
+ return false, cfe({
+ name="openntpd.model.addremove_config(add)",
+ errtxt="You need to enter a value to add!",
+ })
+ end
+ if not (variable) then
+ return false, cfe({
+ name="openntpd.model.addremove_config(add)",
+ errtxt="You need to enter a variable for the value to add!",
+ })
+ end
+
+ local alreadyexists
+ for k,v in pairs(filecontentarray) do
+-- if (string.find(v,"^.-%s+" .. value .. "%s*$" )) then
+ if (string.find(v,"^%s*" .. variable .. "%s*" .. value .. "%s*$" )) then
+ alreadyexists = k
+ break
+ end
+ end
+
+ if (alreadyexists) then
+ return false, cfe({
+ name="openntpd.model.addremove_config(add)",
+ errtxt="The entered record already exists in the config!",
+ })
+ end
+
+ table.insert(filecontentarray, variable .. " " .. value )
+ fs.write_file(file, table.concat(filecontentarray, "\n"))
+
+ return true, cfe({
+ name="openntpd.model.addremove_config(add)",
+ descr="* Record was successfully added!",
+ })
+ else
+ return false, cfe({
+ name="openntpd.model.addremove_config()",
+ errtxt="Wrong usage of this function!",
+ })
end
- return cmdresult
+ return false, cfe({
+ name="openntpd.model.addremove_config()",
+ errtxt="Something went wrong! You entered '" .. tostring(addremove) .. "' as function.",
+ })
end
-- ################################################################################
-- PUBLIC FUNCTIONS
-function startstop_service ( self, state )
- local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol("ntpd", state)
- cmdresult = {cmdresult=cmdmessage,}
- return cmdresult
+-- action should be a CFE
+function startstop_service ( self, action )
+ local cmd = action.value
+ local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol("ntpd", cmd)
+ action.descr=cmdmessage
+ action.errtxt=cmderror
+ -- Reporting back (true|false, the original acition)
+ return cmdresult,action
end
-function modify_config (self, addremove, file, variable)
- if (file == nil) then file = configfile end
- -- See to that only *my* configs are modyfied.
- if (file == configfile) or (file == confdfile) then
- return addremove_config(addremove, file, variable)
- end
+function modify_config(self, addremove, variable, value)
+ return addremove_config(addremove, variable, value)
end
function modify_opts (self, addremove, file, variable, opts)
@@ -135,42 +200,201 @@ end
function getstatus ()
local path = configfile
local status = {}
+ local config = getconfig()
if not (fs.is_file(path)) then
local file_result,err = fs.write_file(path, "")
end
- status["version"] = string.match(get_version(), "^(%S*)" )
- status["date"] = os.date()
- status["enabled"] = procps.pidof("ntpd")
- status["setstimeonstartup"] = getopts.getoptsfromfile(confdfile,"NTPD_OPTS", "-s")
- status["listenstate"] = server
- status["timechanged"] = last_time_change()
+
+ status.version = cfe({
+ name = "version",
+ label="Program version",
+ value=get_version(),
+ })
+
+ status.status = cfe({
+ name="status",
+ label="Program status",
+ value=procps.pidof("ntpd"),
+ })
+
+ status.date = config.date
+
+ status.setstimeonstartup = config.setstimeonstartup
+
+ status.timechanged = config.timechanged
+
return status
end
function getconfig ()
local path = configfile
local config = {}
- config = getopts.getoptsfromfile(confdfile)
- config["variables"] = config_content(path)
+ local configopts = getopts.getoptsfromfile(confdfile)
+
+ configopts["variables"] = config_content(path)
+
+ config.setstimeonstartup = cfe({
+ name = "setstimeonstartup",
+ label="Sets time directly at startup",
+ value = "No",
+ type="checkbox",
+ })
+ if (getopts.getoptsfromfile(confdfile,"NTPD_OPTS", "-s")) then
+ config.setstimeonstartup.value = "Yes"
+ config.setstimeonstartup.checked = "Yes"
+ end
+
+ config.cmdsavesetstimeonstartup = cfe({
+ name = "cmdsavesetstimeonstartup",
+ label="Save the above settings",
+ value = "Save",
+ type="submit",
+ descr="See above checkbox",
+ })
+
+ config.timechanged = cfe({
+ name = "timechanged",
+ label="Previous time adjustment",
+ value = last_time_change(),
+ })
+
+ config.date = cfe({
+ name = "date",
+ label="Current time",
+ value=os.date(),
+ })
+
+ local options = {}
+ for k,v in pairs(configopts.variables) do
+ if (type(v) == "table") and ( (string.lower(k) == "servers") or (string.lower(k) == "server")) then
+ local srvtype = ""
+ if (string.lower(k) == "servers") then srvtype = " (pool)" end
+ for k1, v1 in pairs(v) do
+ if (v1.value) then
+ table.insert(options,v1.value..srvtype)
+ end
+ end
+ end
+ end
+ config.hosts_list = cfe({
+ name = "hosts_list",
+ label="Timeserver hosts",
+ type="select",
+ option=options,
+ size=#options + 1,
+ descr="In most cases you could use <i><b>pool.ntp.org</b></i> or <i><b>[countryname].pool.ntp.org</i></b> (if listed in <i><b>http://www.pool.ntp.org/</b></i>)."
+ })
+ if (#options < 2) then
+ config.hosts_list.size = 2
+ end
+
+ config.hosts_add = cfe({
+ name = "hosts_add",
+ label="Host to add",
+ })
+
+ local options = {
+ cfe({value="1", label="Val1",}),
+ cfe({value="2", label="Val1",}),
+ }
+ config.hosts_type = cfe({
+ name="hosts_type",
+ label="Type of server",
+ value="2",
+ type="radio",
+ option={
+ cfe({value="servers", label="Server pool",}),
+ cfe({value="server", label="Single server",}),
+ },
+ })
+
+ local options = {}
+ for k,v in pairs(configopts.variables) do
+ if (type(v) == "table") and (string.lower(k) == "listen") then
+ for k1, v1 in pairs(v) do
+ if (v1.value) then
+ table.insert(options,v1.value)
+ end
+ end
+ end
+ end
+ config.listen_list = cfe({
+ name = "listen_list",
+ label="Listen on address",
+ type="select",
+ option=options,
+ size=#options + 1,
+ descr="Empty list = Listening (acting as server) is disabled; '*' = Listen on all local addresses.",
+ })
+ if (#options < 2) then
+ config.listen_list.size = 2
+ end
+
+ config.listen_add = cfe({
+ name = "listen_add",
+ label="New listen address",
+ })
+
+
+ -- DEBUG INFORMATION
+ config.debug = cfe({
+ name = "debug",
+ label="Debug information",
+ value=configopts,
+ })
+
return config
end
function get_logfile ()
- local me = {}
+ local file = {}
local cmdtxt = "cat /var/log/messages | grep ntpd"
local cmd, error = io.popen(cmdtxt ,r)
local cmdoutput = cmd:read("*a")
cmd:close()
- me.value = cmdoutput
- me.cmd = cmdtxt
- return me
+
+ file["filename"] = cfe({
+ name="filename",
+ label="File name",
+ value=cmdtxt,
+ })
+
+ file["filecontent"] = cfe({
+ type="longtext",
+ name="filecontent",
+ label="File content",
+ value=cmdoutput,
+ })
+
+ return file
end
function get_filedetails()
- local filedetails = {}
local path = configfile
- filedetails.details = fs.stat(path)
- filedetails.content = fs.read_file(path)
- return filedetails
+ local filedetails = fs.stat(path)
+ local file = {}
+
+ file["filename"] = cfe({
+ name="filename",
+ label="File name",
+ value=path,
+ })
+ file["filesize"] = cfe({
+ name="filesize",
+ label="File size",
+ value=filedetails.size or 0,
+ })
+ file["mtime"] = cfe({
+ name="mtime",
+ label="File date",
+ value=filedetails.mtime or "---",
+ })
+ file["filecontent"] = cfe({
+ type="longtext",
+ name="filecontent",
+ label="File content",
+ value=fs.read_file(path),
+ })
+ return file
end
function update_filecontent (self, modifications)
diff --git a/openntpd-status-html.lsp b/openntpd-status-html.lsp
index f983398..69065af 100644
--- a/openntpd-status-html.lsp
+++ b/openntpd-status-html.lsp
@@ -1,37 +1,49 @@
-<? local view = ... ?>
-
-<h1>SYSTEM INFO</h1>
+<? local form = ... ?>
+<?
+--[[ 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>")
+--]]
+?>
-<dl>
-<dt>Program status</dt>
-<DD><? if (view.status.enabled) then io.write('Enabled') else io.write('Disabled') end ?></DD>
+<?
+function displayinfo(myform,tags,viewonly)
+ io.write("<DL>")
+ for k,v in pairs(tags) do
+ if (myform[v]) and (myform[v]["value"]) then
+ local val = myform[v]
+ io.write("\t<DT")
+ if (#val.errtxt > 0) then
+ val.class = "error"
+ io.write(" class='error'")
+ end
+ io.write(">" .. val.label .. "</DT>\n")
+ if (viewonly) then
+ io.write("\t\t<DD>" .. val.value .. "\n")
+ else
+ io.write("\t\t<DD>" .. html.form[val.type](val) .. "\n")
+ end
+ if (val.descr) and (#val.descr > 0) then io.write("\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>\n") end
+ if (#val.errtxt > 0) then io.write("\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>\n") end
+ io.write("\t\t</DD>\n")
+ end
+ end
+ io.write("</DL>")
+end
+?>
-<dt>Program version</dt>
-<dd><?= view.status.version ?></dd>
-</dl>
+<H1>SYSTEM INFO</H1>
+<?
+local myform = form.status
+local tags = { "status", "version", }
+displayinfo(myform,tags,"viewonly")
+?>
<H2>PROGRAM SPECIFIC OPTIONS/INFORMATION</H2>
-
-<dl>
-<? --[[ ?>
-<dt>Configured as server (listens)</dt>
-<dd><? io.write(view.status.listenstate) ?></dd>
-<? --]] ?>
-
-<dt>Sets time directly at startup</dt>
-<dd><? if (view.status.setstimeonstartup) then io.write("Yes") else io.write("No") end ?></dd>
-
-<dt>Current time</dt>
-<dd><? io.write(view.status.date) ?></dd>
-
-<dt>Previous time adjustment</dt>
-<dd><? io.write(view.status.timechanged) ?></dd>
-</dl>
-
-<?
---[[ DEBUG INFORMATION
-require("debugs")
-io.write(debugs.variables(view))
---]]
+<?
+local myform = form.status
+local tags = { "setstimeonstartup", "date", "timechanged", }
+displayinfo(myform,tags,"viewonly")
?>
diff --git a/openntpd.menu b/openntpd.menu
index ebbf387..716a2d6 100644
--- a/openntpd.menu
+++ b/openntpd.menu
@@ -1,5 +1,5 @@
#CAT GROUP/DESC TAB ACTION
-Networking 20NTPD_config Status status
-Networking 20NTPD_config Config config
-Networking 20NTPD_config Expert expert
-Networking 20NTPD_config Logfile logfile
+Networking 20NTP Status status
+Networking 20NTP Config config
+Networking 20NTP Expert expert
+Networking 20NTP Logfile logfile