diff options
author | Mika Havela <mika.havela@gmail.com> | 2008-02-29 15:52:45 +0000 |
---|---|---|
committer | Mika Havela <mika.havela@gmail.com> | 2008-02-29 15:52:45 +0000 |
commit | fffd98587d8467dfe8254689e43383031ca42b66 (patch) | |
tree | 95c172315175ceceb3cd27410450cda7341d0e5f | |
parent | ae2b0e0d008d64568c91a578a6090dd44860e2ae (diff) | |
download | acf-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.lsp | 190 | ||||
-rw-r--r-- | openntpd-controller.lua | 363 | ||||
-rw-r--r-- | openntpd-expert-html.lsp | 136 | ||||
-rw-r--r-- | openntpd-logfile-html.lsp | 111 | ||||
-rw-r--r-- | openntpd-model.lua | 320 | ||||
-rw-r--r-- | openntpd-status-html.lsp | 74 | ||||
-rw-r--r-- | openntpd.menu | 8 |
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 |