summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-06-24 15:25:39 +0000
committerTed Trask <ttrask01@yahoo.com>2008-06-24 15:25:39 +0000
commite5b81fd75226b70136264addc95e30cecffce444 (patch)
treecc724394d5202125af7340a256fd5f201af6f6e3
parentbc4c53f27f100f3f0280d4d8d5c2d02e4bc3cfd0 (diff)
downloadacf-tinydns-e5b81fd75226b70136264addc95e30cecffce444.tar.bz2
acf-tinydns-e5b81fd75226b70136264addc95e30cecffce444.tar.xz
Updated tinydns as follows: Renames status to view and basicstatus to status. Added ability to view individual config file / domain. Added link from view to edit actual line. Modified view.
Updated jQuery to latest 1.2.6 git-svn-id: svn://svn.alpinelinux.org/acf/tinydns/trunk@1253 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--tinydns-basicstatus-html.lsp16
-rwxr-xr-xtinydns-config-html.lsp2
-rw-r--r--tinydns-controller.lua9
-rw-r--r--tinydns-edit-html.lsp45
-rw-r--r--tinydns-listfiles-html.lsp15
-rw-r--r--tinydns-model.lua73
-rw-r--r--tinydns-status-html.lsp134
-rw-r--r--tinydns-view-html.lsp144
-rw-r--r--tinydns.menu3
-rw-r--r--tinydns.roles2
10 files changed, 234 insertions, 209 deletions
diff --git a/tinydns-basicstatus-html.lsp b/tinydns-basicstatus-html.lsp
deleted file mode 100644
index d0eae68..0000000
--- a/tinydns-basicstatus-html.lsp
+++ /dev/null
@@ -1,16 +0,0 @@
-<? local data = ... ?>
-<? require("viewfunctions") ?>
-<? --[[
-io.write(html.cfe_unpack(data))
---]] ?>
-
-<H1>SYSTEM INFO</H1>
-<DL>
-<?
-displayitem(data.value.status)
-displayitem(data.value.version)
-displayitem(data.value.autostart)
-displayitem(data.value.configdir)
-displayitem(data.value.listen)
-?>
-</DL>
diff --git a/tinydns-config-html.lsp b/tinydns-config-html.lsp
index 4c56ea3..1119a50 100755
--- a/tinydns-config-html.lsp
+++ b/tinydns-config-html.lsp
@@ -10,7 +10,7 @@ io.write("</span>")
?>
<? if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("basicstatus")
+ viewlibrary.dispatch_component("status")
end ?>
<h1>CONFIGURATION</h1>
diff --git a/tinydns-controller.lua b/tinydns-controller.lua
index b0f4272..c97bca2 100644
--- a/tinydns-controller.lua
+++ b/tinydns-controller.lua
@@ -1,4 +1,5 @@
module(..., package.seeall)
+require("validator")
-- ################################################################################
-- LOCAL FUNCTIONS
@@ -8,12 +9,12 @@ module(..., package.seeall)
default_action = "status"
-function basicstatus(self)
+function status(self)
return self.model.getstatus(self)
end
-function status(self)
- return self.model.getconfigobjects(self)
+function view(self)
+ return self.model.getconfigobjects(self.clientdata.filename)
end
function startstop(self)
@@ -107,6 +108,8 @@ function edit(self)
config = self.model.get_filedetails(self.clientdata.filename)
config.descr = "Saved file"
end
+ elseif validator.is_integer(self.clientdata.linenumber) then
+ config.value.filecontent.linenumber = self.clientdata.linenumber
end
config.type = "form"
diff --git a/tinydns-edit-html.lsp b/tinydns-edit-html.lsp
index 6a19c65..95b2fa0 100644
--- a/tinydns-edit-html.lsp
+++ b/tinydns-edit-html.lsp
@@ -16,21 +16,19 @@
this.descriptions[0]=descr0;this.descriptions[1]=descr1;this.descriptions[2]=descr2;this.descriptions[3]=descr3;this.descriptions[4]=descr4;this.descriptions[5]=descr5;this.descriptions[6]=descr6;this.descriptions[7]=descr7;this.descriptions[8]=descr8;this.descriptions[9]=descr9;this.descriptions[10]=descr10;
}
- var entryTypes = new Array(14);
- entryTypes[0]=new Entry("","Empty line",0);
- entryTypes[1]=new Entry(";","Comment line",1,"Comment");
- entryTypes[2]=new Entry("#","Comment line",1,"Comment");
- entryTypes[3]=new Entry(".","Name server",6,"Domain","IP address","Name server","Time to live","Timestamp","Location");
- entryTypes[4]=new Entry("&","Delegate subdomain",6,"Domain","IP address","Name server","Time to live","Timestamp","Location");
- entryTypes[5]=new Entry("=","Host",5,"Host","IP address","Time to live","Timestamp","Location");
- entryTypes[6]=new Entry("+","Alias",5,"Alias","IP address","Time to live","Timestamp","Location");
- entryTypes[7]=new Entry("@","Mail exchanger",7,"Domain","IP address","Mail exchanger","Distance","Time to live","Timestamp","Location");
- entryTypes[8]=new Entry("'","Text record",5,"Domain","Text Record","Time to live","Timestamp","Location");
- entryTypes[9]=new Entry("^","Reverse record",5,"PTR","Domain name","Time to live","Timestamp","Location");
- entryTypes[10]=new Entry("C","Canonical name",5,"Domain","Canonical name","Time to live","Timestamp","Location");
- entryTypes[11]=new Entry("Z","SOA record",11,"Domain","Primary name server","Contact address","Serial number","Refresh time","Retry time","Expire time","Minimum time","Time to live","Timestamp","Location");
- entryTypes[12]=new Entry(":","Generic record",6,"Domain","Record type","Record data","Time to live","Timestamp","Location");
- entryTypes[13]=new Entry("%","Client location",2,"Location","IP prefix");
+ var entryTypes = new Array(12);
+ entryTypes[0]=new Entry("","Comment line",1,"Comment");
+ entryTypes[1]=new Entry(".","Name server",6,"Domain","IP address","Name server","Time to live","Timestamp","Location");
+ entryTypes[2]=new Entry("&","Delegate subdomain",6,"Domain","IP address","Name server","Time to live","Timestamp","Location");
+ entryTypes[3]=new Entry("=","Host",5,"Host","IP address","Time to live","Timestamp","Location");
+ entryTypes[4]=new Entry("+","Alias",5,"Alias","IP address","Time to live","Timestamp","Location");
+ entryTypes[5]=new Entry("@","Mail exchanger",7,"Domain","IP address","Mail exchanger","Distance","Time to live","Timestamp","Location");
+ entryTypes[6]=new Entry("'","Text record",5,"Domain","Text Record","Time to live","Timestamp","Location");
+ entryTypes[7]=new Entry("^","Reverse record",5,"PTR","Domain name","Time to live","Timestamp","Location");
+ entryTypes[8]=new Entry("C","Canonical name",5,"Domain","Canonical name","Time to live","Timestamp","Location");
+ entryTypes[9]=new Entry("Z","SOA record",11,"Domain","Primary name server","Contact address","Serial number","Refresh time","Retry time","Expire time","Minimum time","Time to live","Timestamp","Location");
+ entryTypes[10]=new Entry(":","Generic record",6,"Domain","Record type","Record data","Time to live","Timestamp","Location");
+ entryTypes[11]=new Entry("%","Client location",2,"Location","IP prefix");
function finishForm(entry){
var entrytext = entry.find("select").val() + entry.find("input").map(function(){
@@ -44,17 +42,23 @@
var form = '<select>';
var typechar = entrytext.charAt(0);
if (typechar === null) { typechar = ""; }
- for (i=0; i<14; i++) {
+ for (i=0; i<12; i++) {
form = form + '<option ';
if (typechar == entryTypes[i].entryType){
entryType=entryTypes[i];
form = form + 'selected ';
}
- form = form + 'value="' + entryTypes[i].entryType + '">' + entryTypes[i].entryType + ' (' + entryTypes[i].descr + ')</option>';
+ form = form + 'value="' + entryTypes[i].entryType + '">' + entryTypes[i].descr + '</option>';
}
form = form + "</select><br><dl>";
- entrytext = entrytext.substring(1,entrytext.length) + "::::::::::";
- var entries = entrytext.split(":");
+ var entries;
+ if (entryType.entryType == ""){
+ entries = new Array(1);
+ entries[0] = entrytext;
+ } else {
+ entrytext = entrytext.substring(1,entrytext.length) + "::::::::::";
+ entries = entrytext.split(":");
+ }
for (i=0; i<entryType.num; i++){
if (entries[i] === null) { entries[i] = ""; }
form = form + '<dt>' + entryType.descriptions[i] + '</dt><dd><input type="text" value="' + entries[i] + '"></dd>';
@@ -110,6 +114,9 @@
$(function(){
addLinks($("#entries").find("tr"));
$("input.submit").click(submitFile);
+ <? if form.value.filecontent.linenumber then ?>
+ $("#entries tr:eq(<?= form.value.filecontent.linenumber - 1 ?>)").find("a:eq(2)").click().parent().next().focus();
+ <? end ?>
});
</script>
diff --git a/tinydns-listfiles-html.lsp b/tinydns-listfiles-html.lsp
index f61ce25..c2407e2 100644
--- a/tinydns-listfiles-html.lsp
+++ b/tinydns-listfiles-html.lsp
@@ -9,12 +9,8 @@ io.write("</span>")
--]]
?>
-<? if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("basicstatus")
-end ?>
-
<h1>CONFIGURATION</h1>
-<h2>Edit/View existing config files</h2>
+<h2>Edit/View existing Domains</h2>
<TABLE>
<TR style="background:#eee;font-weight:bold;">
<TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD>
@@ -26,8 +22,9 @@ end ?>
<TR>
<TD style="padding-right:20px;white-space:nowrap;">
<? io.write(html.link{value = "delete?filename=" .. file.value.filename.value, label="Delete " }) ?>
+ <? io.write(html.link{value = "view?filename=" .. file.value.filename.value, label="View " }) ?>
<? io.write(html.link{value = "edit?filename=" .. file.value.filename.value, label="Edit " }) ?>
- <? io.write(html.link{value = "expert?filename=" .. file.value.filename.value, label="View " }) ?>
+ <? io.write(html.link{value = "expert?filename=" .. file.value.filename.value, label="Expert " }) ?>
</TD>
<TD style="padding-right:20px;white-space:nowrap;text-align:right;"><?= file.value.filesize.value ?></TD>
<TD style="padding-right:20px;white-space:nowrap;"><?= file.value.mtime.value ?></TD>
@@ -38,12 +35,8 @@ end ?>
<? if viewlibrary and viewlibrary.dispatch_component then
local newfileform = viewlibrary.dispatch_component("newfile", nil, true) ?>
-<h2>Create new config file</h2>
+<h2>Create new Domain</h2>
<?
newfileform.action = "newfile"
displayform(newfileform)
end ?>
-
-<? if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("startstop")
-end ?>
diff --git a/tinydns-model.lua b/tinydns-model.lua
index e75f937..43bf8ea 100644
--- a/tinydns-model.lua
+++ b/tinydns-model.lua
@@ -89,7 +89,7 @@ local function split_config_items(orgitem)
local output = {}
output = format.string_to_table(string.sub(orgitem,2),delimiter)
output.type = string.sub(orgitem,1,1)
- output.label = descr['prefix'][output.type] or "unknown"
+ output.label = descr['prefix'][output.type]
return output
end
@@ -199,42 +199,47 @@ end
-- If you enter 'filter_type' (this should be one of the options found in local function check_signs() ) then
-- the output will be filtered to only contain this type of data.
-function getconfigobjects(self, filter_type)
+function getconfigobjects(file_name, filter_type)
local configobjects = {}
--Loop through all available configfiles
for i,filename in pairs(configfiles) do
- local filecontent, fileresult
- fileresult, filecontent = get_value_from_file(filename)
- for j,configline in pairs(filecontent) do
- local domaindetails = {}
- local filecontent_table = split_config_items(configline)
- filecontent_table.configline = configline
-
- -- Use only configs that has a valid prefix
- -- If function is called with some filter options... then show only the filtered values
- if ( not (filter_type) or ((filter_type) and (filter_type == filecontent_table.type)) )
- and (filecontent_table.label)
- then
- local entry = {}
- for i,value in ipairs(filecontent_table) do
- entry[i] = value
+ if not file_name or file_name == filename then
+ local filecontent = fs.read_file_as_array(filename)
+ for linenumber,configline in ipairs(filecontent) do
+ local domaindetails = {}
+ local filecontent_table = split_config_items(configline)
+ filecontent_table.configline = configline
+
+ -- Use only configs that has a valid prefix
+ -- If function is called with some filter options... then show only the filtered values
+ if ( not (filter_type) or ((filter_type) and (filter_type == filecontent_table.type)) )
+ and (filecontent_table.label)
+ then
+ local entry = {}
+ for i,value in ipairs(filecontent_table) do
+ entry[i] = value
+ end
+ -- add in the filename and line number
+ entry.filename = filename
+ entry.linenumber = linenumber
+
+ -- we're gonna add a reverse domain name to make it easier to sort
+ local domain = {}
+ for mt in string.gmatch(entry[1], "([^.]+)") do
+ table.insert(domain, mt)
+ end
+ local reversedomain = {}
+ for i=#domain,1,-1 do
+ table.insert(reversedomain, domain[i])
+ end
+ entry.sort = table.concat(reversedomain, ".")
+
+ -- add it to the table
+ if not configobjects[filecontent_table.type] then
+ configobjects[filecontent_table.type] = {label=filecontent_table.label, fieldlabels=descr.fieldlabels[filecontent_table.type]}
+ end
+ table.insert(configobjects[filecontent_table.type], entry)
end
- -- we're gonna add a reverse domain name to make it easier to sort
- local domain = {}
- for mt in string.gmatch(entry[1], "([^.]+)") do
- table.insert(domain, mt)
- end
- local reversedomain = {}
- for i=#domain,1,-1 do
- table.insert(reversedomain, domain[i])
- end
- entry.sort = table.concat(reversedomain, ".")
-
- -- add it to the table
- if not configobjects[filecontent_table.type] then
- configobjects[filecontent_table.type] = {label=filecontent_table.label, fieldlabels=descr.fieldlabels[filecontent_table.type]}
- end
- table.insert(configobjects[filecontent_table.type], entry)
end
end
end
@@ -261,7 +266,7 @@ function getconfigobjects(self, filter_type)
end
end
- return configobjects
+ return cfe({ type="structure", value=configobjects, label="DNS Entries", filename=file_name })
end
function getfilelist ()
diff --git a/tinydns-status-html.lsp b/tinydns-status-html.lsp
index ca0ddf4..d0eae68 100644
--- a/tinydns-status-html.lsp
+++ b/tinydns-status-html.lsp
@@ -1,128 +1,16 @@
-<? local view, viewlibrary = ...
-require("viewfunctions")
-?>
-
-<script type="text/javascript" src="/js/jquery-latest.js"></script>
-<script type="text/javascript">
- var last_phrase = "";
- function filterPage(){
- var phrase = $("#filter").val();
- if (phrase != last_phrase){
- last_phrase = phrase;
- $("#records li").each(function(){
- var elem = jQuery(this);
- if (elem.text().indexOf(phrase)>=0) {
- elem.show();
- } else {
- elem.hide();
- }
- });
- }
- }
- var filterTimer;
- $(function(){
- $("#filter").keyup(function(){
- window.clearTimeout(filterTimer);
- filterTimer = window.setTimeout("filterPage();",250);
- });
- $("#filter-list").submit(function(){
- return false;
- }).focus();
- });
-</script>
-
-<?
---[[ DEBUG INFORMATION
-io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(view))
-io.write("</span>")
---]]
-?>
-
-<? if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("basicstatus")
-end ?>
+<? local data = ... ?>
+<? require("viewfunctions") ?>
+<? --[[
+io.write(html.cfe_unpack(data))
+--]] ?>
-<H1>PROGRAM SPECIFIC OPTIONS/INFORMATION</H1>
-<H2>Locations</H2>
+<H1>SYSTEM INFO</H1>
<DL>
<?
-if (view) and (view['%']) then
- local val = view['%'] ?>
- <DT<? if (val.errtxt) then io.write(" class='error'") end ?>><?= val.label ?></DT>
-
- <DD>
- <? local currentloc = ""
- for i,loc in ipairs(val) do
- if currentloc ~= loc[1] then ?>
- <IMG SRC='/skins/static/tango/16x16/places/start-here.png' width='16' height='16' alt> <B><?= loc[1] ?></B>
- <? end
- currentloc = loc[1] ?>
- <BR><SPAN STYLE='margin-left:30px;'><?= loc[2] ?></SPAN><BR>
- <? if (loc.errtxt) then ?><P CLASS='error'><?= string.gsub(loc.errtxt, "\n", "<BR>") ?></P><? end ?>
- <? end ?>
- </DD>
-<? end ?>
-</DL>
-
-<?
-local function doListIndents(next, indent)
- local newentry = {}
- for mt in string.gmatch(next, "([^.]+)") do
- table.insert(newentry, mt)
- end
- local revnewentry = {}
- for j=#newentry,1,-1 do
- table.insert(revnewentry, newentry[j])
- end
- local i=1
- while indent[i] and revnewentry[i] == indent[i] do
- i=i+1
- end
- local ending = #indent-(i-1)
- local starting = #newentry-(i-1)
- for j=1,ending do
- io.write("</li></ul>\n")
- end
- for j=1,starting do
- io.write("<ul><li STYLE='margin-left:10px;'><strong>")
- io.write(table.concat(newentry, ".", #newentry-(i+j-2), #newentry))
- io.write("</strong>\n")
- end
- return revnewentry
-end
+displayitem(data.value.status)
+displayitem(data.value.version)
+displayitem(data.value.autostart)
+displayitem(data.value.configdir)
+displayitem(data.value.listen)
?>
-
-<H2>Records</H2>
-<form id="filter-list">Filter: <input name="filter" id="filter" value="" maxlength="30" size="30" type="text"></form>
-<DL id="records">
-<?
-local tags = {".", "&", "=", "+", "@", "'", "^", "C", "Z", ":" }
-for i,entrytype in ipairs(tags) do
- local myview = view[entrytype]
- if (myview) then ?>
- <DT><?= myview.label ?></DT>
- <DD><ul>
- <? local indent = {}
- for j,entry in ipairs(myview) do
- indent = doListIndents(entry[1], indent) ?>
- <ul><li STYLE='margin-left:10px;'><IMG SRC='/skins/static/tango/16x16/devices/computer.png' width='16' height='16'><?= tostring(entry[1]) ?><BR>
- <TABLE STYLE='margin-left:<?= tostring(7-#indent) ?>0px;'>
- <? for k=2,#entry do
- local option = entry[k]
- if (option) and option ~= "" then ?>
- <TR><TD WIDTH='160px' STYLE='border:none;'><?= myview.fieldlabels[k] ?>:</TD>
- <TD STYLE='border:none;'><?= option ?></TD></TR>
- <? end
- end ?>
- </TABLE>
- <? if entry.errtxt then ?>
- <P CLASS='error'><?= string.gsub(entry.errtxt, "\n", "<BR>") ?></P>
- <? end ?>
- </li></ul>
- <? end
- doListIndents("", indent) ?>
- </ul></DD>
- <? end
-end ?>
</DL>
diff --git a/tinydns-view-html.lsp b/tinydns-view-html.lsp
new file mode 100644
index 0000000..8ec8b9e
--- /dev/null
+++ b/tinydns-view-html.lsp
@@ -0,0 +1,144 @@
+<? local view, viewlibrary = ...
+require("viewfunctions")
+?>
+
+<script type="text/javascript" src="/js/jquery-latest.js"></script>
+<script type="text/javascript">
+ var last_phrase = "";
+ function filterPage(){
+ var phrase = $("#filter").val();
+ if (phrase != last_phrase){
+ last_phrase = phrase;
+ $("#records li").each(function(){
+ var elem = jQuery(this);
+ if (elem.text().indexOf(phrase)>=0) {
+ elem.show();
+ } else {
+ elem.hide();
+ }
+ });
+ }
+ }
+ function editEntry(){
+ window.location.href = "edit?" + this.id;
+ }
+ var filterTimer;
+ $(function(){
+ $("#filter").keyup(function(){
+ window.clearTimeout(filterTimer);
+ filterTimer = window.setTimeout("filterPage();",250);
+ });
+ $("#filter-list").submit(function(){
+ return false;
+ }).focus();
+ $("#records li").not(":has(ul)").dblclick(editEntry);
+ $("#locations li").not(":has(ul)").dblclick(editEntry);
+ });
+</script>
+
+<?
+--[[ DEBUG INFORMATION
+io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
+io.write(html.cfe_unpack(view))
+io.write("</span>")
+--]]
+?>
+
+<H1>DNS Entries
+<? if view.filename then io.write(" for "..view.filename) end ?>
+</H1>
+<H2>Locations</H2>
+<DL id="locations">
+<?
+if (view.value) and (view.value['%']) then
+ local val = view.value['%'] ?>
+ <DT<? if (val.errtxt) then io.write(" class='error'") end ?>><?= val.label ?></DT>
+
+ <DD><ul>
+ <? local currentloc = ""
+ for i,loc in ipairs(val) do
+ if currentloc ~= loc[1] then
+ if currentloc ~= "" then ?>
+ </ul>
+ <? end ?>
+ <li><IMG SRC='/skins/static/tango/16x16/places/start-here.png' width='16' height='16' alt> <B><?= loc[1] ?></B></li>
+ <ul STYLE='margin-left:30px';>
+ <? end
+ currentloc = loc[1] ?>
+ <li id='filename=<?= loc.filename ?>;linenumber=<?= loc.linenumber ?>'>
+ <?= loc[2] ?><? if loc[2] == "" then io.write('*') end ?>
+ <? if (loc.errtxt) then ?><P CLASS='error'><?= string.gsub(loc.errtxt, "\n", "<BR>") ?></P><? end ?>
+ </li>
+ <? end
+ if currentloc ~= "" then ?>
+ </ul>
+ <? end ?>
+ </ul>
+ </DD>
+<? else ?>
+ No locations defined
+<? end ?>
+</DL>
+
+<?
+local function doListIndents(next, indent)
+ local newentry = {}
+ for mt in string.gmatch(next, "([^.]+)") do
+ table.insert(newentry, mt)
+ end
+ local revnewentry = {}
+ for j=#newentry,1,-1 do
+ table.insert(revnewentry, newentry[j])
+ end
+ local i=1
+ while indent[i] and revnewentry[i] == indent[i] do
+ i=i+1
+ end
+ local ending = #indent-(i-1)
+ local starting = #newentry-(i-1)
+ for j=1,ending do
+ io.write("</li></ul>\n")
+ end
+ for j=1,starting do
+ io.write("<ul><li STYLE='margin-left:10px;'><strong>")
+ io.write(table.concat(newentry, ".", #newentry-(i+j-2), #newentry))
+ io.write("</strong>\n")
+ end
+ return revnewentry
+end
+?>
+
+<H2>Records</H2>
+<form id="filter-list">Filter: <input name="filter" id="filter" value="" maxlength="30" size="30" type="text"></form>
+<DL id="records">
+<?
+local tags = {".", "&", "=", "+", "@", "'", "^", "C", "Z", ":" }
+for i,entrytype in ipairs(tags) do
+ local myview = view.value[entrytype]
+ if (myview) then ?>
+ <DT><?= myview.label ?></DT>
+ <DD><ul>
+ <? local indent = {}
+ for j,entry in ipairs(myview) do
+ indent = doListIndents(entry[1], indent) ?>
+ <ul><li STYLE='margin-left:10px;' id='filename=<?= entry.filename ?>;linenumber=<?= entry.linenumber ?>'>
+ <IMG SRC='/skins/static/tango/16x16/devices/computer.png' width='16' height='16'><?= tostring(entry[1]) ?><BR>
+ <TABLE STYLE='margin-left:<?= tostring(7-#indent) ?>0px;'>
+ <? for k=2,#entry do
+ local option = entry[k]
+ if (option) and option ~= "" then ?>
+ <TR><TD WIDTH='160px' STYLE='border:none;'><?= myview.fieldlabels[k] ?>:</TD>
+ <TD STYLE='border:none;'><?= option ?></TD></TR>
+ <? end
+ end ?>
+ </TABLE>
+ <? if entry.errtxt then ?>
+ <P CLASS='error'><?= string.gsub(entry.errtxt, "\n", "<BR>") ?></P>
+ <? end ?>
+ </li></ul>
+ <? end
+ doListIndents("", indent) ?>
+ </ul></DD>
+ <? end
+end ?>
+</DL>
diff --git a/tinydns.menu b/tinydns.menu
index 70984b4..5243d05 100644
--- a/tinydns.menu
+++ b/tinydns.menu
@@ -1,4 +1,5 @@
#CAT GROUP/DESC TAB ACTION
Networking 10DNS Status status
+Networking 10DNS View view
+Networking 10DNS List_Domains listfiles
Networking 10DNS Config config
-Networking 10DNS List_Files listfiles
diff --git a/tinydns.roles b/tinydns.roles
index 45a2655..d473bb7 100644
--- a/tinydns.roles
+++ b/tinydns.roles
@@ -1,2 +1,2 @@
-READ=tinydns:status,tinydns:basicstatus
+READ=tinydns:status,tinydns:view
UPDATE=tinydns:config,tinydns:listfiles,tinydns:delete,tinydns:edit,tinydns:expert,tinydns:newfile,tinydns:startstop