Commit 7675a312 authored by Ted Trask's avatar Ted Trask

Added config to fetchmail to configure globals and multiple entries. Also...

Added config to fetchmail to configure globals and multiple entries.  Also added ability to run once and test.  Still need support for ETRN and SSL.

git-svn-id: svn://svn.alpinelinux.org/acf/fetchmail/trunk@1437 ab2d0c66-481e-0410-8bed-d214d4d58bed
parent 0441e224
<% local form = ...
require("viewfunctions")
%>
<%
--[[ DEBUG INFORMATION
io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
io.write(html.cfe_unpack(form))
io.write("</span>")
--]]
%>
<% local view, viewlibrary, page_info, session = ... %>
<% require("viewfunctions") %>
<H1>SYSTEM INFO</H1>
<DL>
<%
local myform = form.status
local tags = { "status", "version", "autostart", }
displayinfo(myform,tags,"viewonly")
%>
</DL>
<H1>CONFIGURATION</H1>
<% local myform = form.config %>
<form action="<%= form.option.script .. "/" .. form.option.prefix ..
form.option.controller .. "/" .. form.option.action %>" method="POST">
<% displaycommandresults({"deleteentry"}, session) %>
<H2>GUIDED CONFIGURATION</H2>
<% --[[ %>
<H3>FREQUENCY</H3>
<P>Select how often the mailboxes will be checked. For ETRN transfers (below) this specifies how often transfers are initiated</P>
<%
local tags = { "freq", }
displayinfo(myform,tags)
%>
<% --]] %>
<% if viewlibrary and viewlibrary.dispatch_component then
viewlibrary.dispatch_component("status")
end %>
<H3>MAILBOXES</H3>
<P>You will need to specify the remote mailbox and password, as well as the local (internal) mailbox to forward the mail to. The SMTP host is the name or address of the SMTP server to send the mail to.</P>
<P>If you want to use POP3 account for the entire domain, selecting the <U>pop3domain</U> method will setup the appropriate configuration for retrieving and distributing the mail appropriately. The <B>domain</B> information should be your internet smtp domain. The <B>mailbox</B> field is ignored when this method is selected.</P>
<H1>Global Settings</H1>
<P>When selecting the <U>pop3</U> or <U>imap</U> methods, the <B>domain</B> field should be left blank.</P>
<% -- START - SPECIAL VIEW FOR SHOWING AVAILABLE MAILBOXES %>
<%
local tags = "mailboxes"
local mailboxform = myform[tags]["value"]
%>
<DL>
<%
io.write("\n\t<CENTER><TABLE STYLE='border:1px solid #ccc;background:#eee'>\n\t\t<TR>\n\t\t\t<TD CLASS='header' WIDTH='150px'>")
io.write("<CENTER>METHOD</CENTER></TD>\n\t\t\t<TD CLASS='header' COLSPAN=2>")
io.write("<CENTER>REMOTE</CENTER></TD>\n\t\t\t<TD CLASS='header' COLSPAN=2>")
io.write("<CENTER>LOCAL</CENTER></TD>\n\t\t</TR>")
for i=1, table.maxn(mailboxform) do
leftpadd="30px"
rightpadd="5px"
io.write("\n\t\t<TR>\n\t\t\t<TD>")
val = "method"
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";' WIDTH='5%'>")
val = "remotehost"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";' WIDTH='5%'>")
val = "localhost"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t</TR>")
io.write("\n\t\t<TR>\n\t\t\t<TD>")
val = "disabled"
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write(" " .. mailboxform[i][val]["label"])
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";'>")
val = "remotemailbox"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";'>")
val = "localmailbox"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t</TR>")
io.write("\n\t\t<TR>\n\t\t\t<TD>")
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";'>")
val = "remotepassword"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t\t<TD style='padding-left:".. leftpadd .. ";padding-right:".. rightpadd .. ";'>")
val = "localdomain"
io.write(mailboxform[i][val]["label"])
io.write(":</TD>\n\t\t\t<TD>")
io.write(html.form[mailboxform[i][val]["type"]](mailboxform[i][val]))
io.write("</TD>\n\t\t</TR>")
io.write("\n\t\t<TR>\n\t\t\t<TD COLSPAN=5><HR></TD>\n\t\t</TR>")
end
io.write("</TABLE></CENTER>")
%>
<dt>Edit global settings</dt>
<dd><form action="<%= page_info.script .. page_info.prefix .. page_info.controller .. "/editconfig" %>" method="POST">
<input type=submit value="Edit" class="submit">
</form></dd>
</DL>
<% -- START - SPECIAL VIEW FOR SHOWING AVAILABLE MAILBOXES %>
<H3>LAST RESORT</H3>
<P>The Postmaster address is the address of last resort when fetchmail cannot determine how to send a mail message. If left blank, undelieverable mail may be discarded.</P>
<%
local tags = { "postmaster", }
displayinfo(myform,tags)
%>
<H3>ETRN</H3>
<P>This is for branches that have DNS mail domains hosted by an ISP that allows for ETRN dequeueing. ETRN dequeueing causes the SMTP mail exchanger at the ISP to forward mail to you via SMTP. You will need to make sure that DNS is setup appropriately and that your ISP supports ETRN. If you have not arranged with your ISP to have ETRN support, leave these fields blank.</P>
<%
local tags = { "etrnremote","etrnquedomain", }
displayinfo(myform,tags)
%>
<% --[[ %>
<H2>ADVANCED CONFIGURATION</H2>
<H3>GENERAL</H3>
<%
local tags = { "logfile", "loglevel", "smallerlogs", }
displayinfo(myform,tags)
%>
<% --]] %>
<H2>SAVE AND APPLY ABOVE SETTINGS</H2>
<%
local tags = { "cmdsave","cmdtest", }
displayinfo(myform,tags)
%>
</form>
<%
local cmdform = form.management
local tags = { "start", "stop", "restart" }
if (cmdform) and (cmdform[tags[1]]) then
%>
<form name="management" action="" method="POST">
<H1>MANAGEMENT</H1>
<dl>
<dt><%= cmdform[tags[1]]["label"] %></dt>
<dd>
<% for k,v in pairs(tags) do %>
<% if (cmdform[v]) then %>
<% io.write(html.form[cmdform[v].type](cmdform[v])) %>
<% end %>
<% end %>
</dd>
<% if (form.cmdmanagement) and (#form.cmdmanagement.descr > 0) then %>
<dt>Previous action result</dt>
<dd><pre><%= form.cmdmanagement.descr %></pre></dd>
<% end %>
</dl>
</form>
<% if viewlibrary and viewlibrary.dispatch_component then
viewlibrary.dispatch_component("listentries")
end %>
<% end %>
<% if viewlibrary and viewlibrary.dispatch_component then
viewlibrary.dispatch_component("startstop")
end %>
......@@ -11,11 +11,27 @@ end
function startstop(self)
return controllerfunctions.handle_startstop(self, self.model.startstop_service, self.model.getstatus, self.clientdata)
end
--[[
function config(self)
function editconfig(self)
return controllerfunctions.handle_form(self, self.model.getconfig, self.model.updateconfig, self.clientdata, "Save", "Edit Config", "Configuration Set")
end
--]]
function expert(self)
return controllerfunctions.handle_form(self, self.model.get_filedetails, self.model.update_filecontent, self.clientdata, "Save", "Edit Config", "Configuration Set")
end
function listentries(self)
return self.model.readentries()
end
function editentry(self)
return controllerfunctions.handle_form(self, function() return self.model.readentry(self.clientdata.entry) end, self.model.updateentry, self.clientdata, "Save", "Edit Entry", "Entry Saved")
end
function createentry(self)
return controllerfunctions.handle_form(self, self.model.readentry, self.model.createentry, self.clientdata, "Create", "Create Entry", "Entry Created")
end
function deleteentry(self)
return self:redirect_to_referrer(self.model.deleteentry(self.clientdata.entry))
end
fetchmail-editentry-html.lsp
\ No newline at end of file
../form-html.lsp
\ No newline at end of file
<% local form, viewlibrary, page_info = ...
require("viewfunctions")
%>
<H1><%= form.label %></H1>
<%
form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action
if page_info.action == "editentry" then
form.value.remotehost.contenteditable = false
end
local order = { "remotehost", "enabled", "method", "remotemailbox", "remotepassword", "localhost", "localmailbox", "localdomain" }
displayform(form, order)
%>
<% local data, viewlibrary, page_info, session = ...
require("viewfunctions")
%>
<%
--[[ DEBUG INFORMATION
io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
io.write(html.cfe_unpack(data))
io.write("</span>")
--]]
%>
<% displaycommandresults({"deleteentry"}, session) %>
<h1>Edit/View Fetchmail Entries</h1>
<DL>
<TABLE>
<TR style="background:#eee;font-weight:bold;">
<TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD>
<TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Entry</TD>
<TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Enabled</TD>
<TD style="white-space:nowrap;text-align:left;" class="header">Method</TD>
</TR>
<% for i,entry in ipairs(data.value) do %>
<TR>
<TD style="padding-right:20px;white-space:nowrap;">
<% io.write(html.link{value = "editentry?entry=" .. entry.entry, label="Edit " }) %>
<% io.write(html.link{value = "deleteentry?entry=" .. entry.entry, label="Delete " }) %>
</TD>
<TD style="padding-right:20px;white-space:nowrap;"><%= entry.entry %></TD>
<TD style="padding-right:20px;white-space:nowrap;"><%= entry.enabled %></TD>
<TD style="white-space:nowrap;" width="90%"><%= entry.method %></TD>
</TR>
<% end %>
</TABLE>
<DT>Add new entry</DT>
<DD><form action="<%= page_info.script .. page_info.prefix .. page_info.controller .. "/createentry" %>" method="POST">
<input type=submit value="New" class="submit">
</form></DD>
</DL>
......@@ -2,186 +2,304 @@ module(..., package.seeall)
-- Load libraries
require("modelfunctions")
require("posix")
require("fs")
require("getopts")
require("validator")
-- Set variables
local packagename = "fetchmail"
local processname = "fetchmail"
local configfile = "/root/.fetchmailrc"
local config = {}
local configfile = "/etc/fetchmailrc"
local confdfile = "/etc/conf.d/fetchmail"
local config
local methods = {"pop3","imap","pop3domain", }
-- ################################################################################
-- LOCAL FUNCTIONS
local function getloglevels()
local loglevels = {}
for i=1,8 do
table.insert(loglevels,i)
end
return loglevels
end
local function getmethods()
local methods = {"pop3","imap","pop3domain", }
return methods
end
local function getmailboxes(t)
local objects = cfe({})
objects.label = "Mailbox " .. tostring(t["RBOX"])
objects.method = cfe({
name="method",
label = "Method",
type = "select",
value = t["METHOD"],
option = getmethods(),
})
objects.disabled = cfe({
name="disabled",
type="checkbox",
label = "Disabled",
checked = t["DISABLED"],
})
objects.remotehost = cfe({
name="remotehost",
label = "RemoteHost",
value = t["RHOST"],
})
objects.remotemailbox = cfe({
name="remotemailbox",
label = "Mailbox",
value = t["RBOX"],
})
objects.remotepassword = cfe({
name="remotepassword",
label = "Password",
type = "passwd",
value = t["PASSWD"],
})
objects.localhost = cfe({
name="localhost",
label = "LocalHost",
value = t["LHOST"],
})
objects.localmailbox = cfe({
name="localmailbox",
label = "LocalMailbox",
value = t["LBOX"],
})
objects.localdomain = cfe({
name="localdomain",
label = "LocalDomain",
value = t["DOMAIN"],
})
return objects
end
local function read_config()
--[[
imap/pop3 lines are:
1 2 3 4 5 6 7 8 9 10
poll <host> protocol <proto> no dns username <uname> password <passwd>
11 12 13 14 15 16 17
is <localmailbox> smtphost <desthost> no rewrite fetchall
pop3domain lines are:
1 2 3 4 5 6 7 8 9 10 11 12
poll <host> localdomainst <domain> protocol pop3 no dns username <uname> password <passwd>
13 14 15 16 17 18 19 20 21 22
to * here smtphost <desthost> smtpaddress <domain> no rewrite fetchall
etrn is:
1 2 3 4 5 6
pool <host> protocol etrn smtpdomain <mydomain>
--]]
local mailboxes = {}
local configcontent_postmaster = {}
local configcontent_etrn = {}
local path = configfile
local valid = nil
configcontenttable = fs.read_file_as_array(path) or {}
for k,v in pairs(configcontenttable) do
if (string.match(v, "^%s*#Begin Fetchmail")) then valid=1 end
if (valid) then
--
local DISABLED = string.match(v, "^%s*(#)")
-- Set parameters for POP3 or IMAP
local val = {RHOST=2, CHECK=9 ,METHOD=4, RBOX=8, PASSWD=10, LBOX=12, LHOST=14}
local configcontent = {}
configcontent[k] = {}
configcontent[k]["DISABLED"] = DISABLED
for kk,vv in pairs(val) do
configcontent[k][kk] = tostring(string.match(v,"^%s*" .. string.rep("%S*%s*",vv-1) .. "(%S*)%s*"))
end
-- Remove quotes from passwords
if (configcontent[k]["PASSWD"]) then
configcontent[k]["PASSWD"] = string.match(configcontent[k]["PASSWD"], "^\"(.-)\"")
end
-- Check if row is valid config
if (configcontent[k]["CHECK"]) and (string.lower(configcontent[k]["CHECK"]) == "password") then
table.insert(mailboxes,getmailboxes(configcontent[k]))
end
-- Set parameters for POP3domain
local val = {RHOST=2, METHOD=6, RBOX=10, CHECK=11, PASSWD=12, LHOST=17, DOMAIN=19,}
local configcontent = {}
configcontent[k] = {}
configcontent[k]["DISABLED"] = DISABLED
for kk,vv in pairs(val) do
configcontent[k][kk] = tostring(string.match(v,"^%s*" .. string.rep("%S*%s*",vv-1) .. "(%S*)%s*"))
end
-- Display this config as Method=pop3domain (as the current options in the view)
configcontent[k]["METHOD"] = "pop3domain"
-- Remove quotes from passwords
if (configcontent[k]["PASSWD"]) then
configcontent[k]["PASSWD"] = string.match(configcontent[k]["PASSWD"], "^\"(.-)\"")
end
-- Check if row is valid config
if (configcontent[k]["CHECK"]) and (string.lower(configcontent[k]["CHECK"]) == "password") then
table.insert(mailboxes,getmailboxes(configcontent[k]))
end
-- Set parameters for etrn
local val = {ETRNSMTPHOST=2, CHECK=4, ETRNDOMAIN=6}
local configcontent = {}
configcontent[k] = {}
configcontent[k]["DISABLED"] = DISABLED
for kk,vv in pairs(val) do
configcontent[k][kk] = tostring(string.match(v,"^%s*" .. string.rep("%S*%s*",vv-1) .. "(%S*)%s*"))
end
-- Check if row is valid config
if (configcontent[k]["CHECK"]) and (string.lower(configcontent[k]["CHECK"]) == "etrn") then
configcontent_etrn=configcontent[k]
end
-- Set parameters for postmaster
local val = {CHECK=2, POSTMASTER=3}
local configcontent = {}
configcontent[k] = {}
configcontent[k]["DISABLED"] = DISABLED
for kk,vv in pairs(val) do
configcontent[k][kk] = tostring(string.match(v,"^%s*" .. string.rep("%S*%s*",vv-1) .. "(%S*)%s*"))
end
-- Check if row is valid config
if (configcontent[k]["CHECK"]) and (string.lower(configcontent[k]["CHECK"]) == "postmaster") then
configcontent_postmaster=configcontent[k]
end
end
if (string.match(v, "^%s*#End Fetchmail")) then valid=nil end
end
-- Create one empty record so that user can add settings
table.insert(mailboxes,getmailboxes({}))
return mailboxes,configcontent_postmaster,configcontent_etrn
local function parseconfigfile(file)
file = file or ""
local retval = {}
local linenum=0
for line in string.gmatch(file, "([^\n]*)\n?") do
linenum=linenum+1
if not string.match(line, "^%s*$") and not string.match(line, "^%s*#") then
table.insert(retval, {linenum=linenum})
-- Iterate through each word, being careful about quoted strings and comments
local offset = 1
while string.find(line, "%S+", offset) do
local word = string.match(line, "%S+", offset)
local endword = select(2, string.find(line, "%S+", offset))
if string.find(word, "^#") then
break
elseif string.find(word, "^\"") then
endword = select(2, string.find(line, "\"[^\"]*\"", offset))
word = string.sub(line, string.find(line, "\"", offset), endword)
end
table.insert(retval[#retval], word)
offset = endword + 1
end
end
end
return retval
end
local function findentryline(entryname)
if entryname and entryname ~= "" then
config = config or parseconfigfile(fs.read_file(configfile))
for i,entry in ipairs(config or {}) do
if (entry[1] == "server" or entry[1] == "poll" or entry[1] == "skip") and entry[2] == entryname then
return entry
end
end
end
return nil
end
local function writeentryline(entrystruct, entryline)
if not entrystruct and not entryline then
return
end
-- If there is a structure, create the entryline array
if entrystruct then
entryline = entryline or {}
if entrystruct.value.enabled.value then
entryline[1] = "poll"
else
entryline[1] = "skip"
end
entryline[2] = entrystruct.value.remotehost.value
local reverseentry = {}
for i,word in ipairs(entryline) do reverseentry[word] = i end
-- server options must come before user options, so add user option to end
-- and add server options just after remotehost (3)
-- start with the user options so we can add to the end and not mess up reverseentry
-- this means that we do method last
if reverseentry["user"] or reverseentry["username"] then
entryline[(reverseentry["user"] or reverseentry["username"])+1] = entrystruct.value.remotemailbox.value
else
entryline[#entryline+1] = "username"
entryline[#entryline+1] = entrystruct.value.remotemailbox.value
end
if reverseentry["pass"] or reverseentry["password"] then
entryline[(reverseentry["pass"] or reverseentry["password"])+1] = '"'..entrystruct.value.remotepassword.value..'"'
else
entryline[#entryline+1] = "password"
entryline[#entryline+1] = '"'..entrystruct.value.remotepassword.value..'"'
end
if reverseentry["smtphost"] then
entryline[reverseentry["smtphost"]+1] = entrystruct.value.localhost.value
else
entryline[#entryline+1] = "smtphost"
entryline[#entryline+1] = entrystruct.value.localhost.value
end
-- add in some user options
if not reverseentry["rewrite"] then
entryline[#entryline+1] = "no"
entryline[#entryline+1] = "rewrite"
end
if not reverseentry["fetchall"] then
entryline[#entryline+1] = "fetchall"
end
-- now handle the method, localmailbox, and localdomain
if entrystruct.value.method.value == "pop3domain" then
if reverseentry["to"] then
entryline[reverseentry["to"]+1] = "*"
else
entryline[#entryline+1] = "to"
entryline[#entryline+1] = "*"
end
if reverseentry["smtpaddress"] then
entryline[reverseentry["smtpaddress"]+1] = entrystruct.value.localdomain.value
else
entryline[#entryline+1] = "smtpaddress"
entryline[#entryline+1] = entrystruct.value.localdomain.value
end
if reverseentry["is"] then
-- THIS MESSES UP reverseentry FOR THE USER OPTIONS
table.remove(entryline, reverseentry["is"])
table.remove(entryline, reverseentry["is"])
end
if reverseentry["proto"] or reverseentry["protocol"] then
entryline[(reverseentry["proto"] or reverseentry["protocol"])+1] = "pop3"
else
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.insert(entryline, 3, "pop3")
table.insert(entryline, 3, "protocol")
-- FIX reverseentry
reverseentry = {}
for i,word in ipairs(entryline) do reverseentry[word] = i end
end
if reverseentry["local"] or reverseentry["localdomains"] then
entryline[(reverseentry["local"] or reverseentry["localdomains"])+1] = entrystruct.value.localdomain.value
else
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.insert(entryline, 3, entrystruct.value.localdomain.value)
table.insert(entryline, 3, "localdomains")
end
if not reverseentry["dns"] then
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.insert(entryline, 3, "dns")
table.insert(entryline, 3, "no")
end
else
if reverseentry["is"] then
entryline[reverseentry["is"]+1] = entrystruct.value.localmailbox.value
else
entryline[#entryline+1] = "is"
entryline[#entryline+1] = entrystruct.value.localmailbox.value
end
if reverseentry["to"] then
-- THIS MESSES UP reverseentry FOR THE USER OPTIONS
table.remove(entryline, reverseentry["to"])
table.remove(entryline, reverseentry["to"])
-- FIX reverseentry
reverseentry = {}
for i,word in ipairs(entryline) do reverseentry[word] = i end
end
if reverseentry["smtpaddress"] then
-- THIS MESSES UP reverseentry FOR THE USER OPTIONS
table.remove(entryline, reverseentry["smtpaddress"])
table.remove(entryline, reverseentry["smtpaddress"])
end
if reverseentry["proto"] or reverseentry["protocol"] then
entryline[(reverseentry["proto"] or reverseentry["protocol"])+1] = entrystruct.value.method.value
else
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.insert(entryline, 3, entrystruct.value.method.value)
table.insert(entryline, 3, "protocol")
-- FIX reverseentry
reverseentry = {}
for i,word in ipairs(entryline) do reverseentry[word] = i end
end
if reverseentry["local"] or reverseentry["localdomains"] then
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.remove(entryline, (reverseentry["local"] or reverseentry["localdomains"]))
table.remove(entryline, (reverseentry["local"] or reverseentry["localdomains"]))
end
if not reverseentry["dns"] then
-- THIS MESSES UP reverseentry FOR EVERYTHING
table.insert(entryline, 3, "dns")
table.insert(entryline, 3, "no")
end
end
-- remove here and there
for i=#entryline,1,-1 do
if entryline[i] == "here" or entryline[i] == "there" then
table.remove(entryline, i)
end
end
end
local file = fs.read_file(configfile)
local lines = {file}
if entryline and entryline.linenum then
-- Split the file to remove the line
local startchar, endchar = string.match(file, string.rep("[^\n]*\n", entryline.linenum-1) .. "()[^\n]*\n()")
if startchar and endchar then
lines[1] = string.sub(file, 1, startchar-1)
lines[2] = string.sub(file, endchar, -1)
end
end
if entryline and entrystruct then
table.insert(lines, 2, table.concat(entryline," ").."\n")
end
fs.write_file(configfile, string.gsub(table.concat(lines), "\n+$", ""))
posix.chmod(configfile, "rwx--x---")
config = nil
end
local function validateentry(entry)
local success = true
success = modelfunctions.validateselect(entry.value.method) and success
if entry.value.remotehost.value == "" then
entry.value.remotehost.errtxt = "Invalid entry - cannot be blank"
success = false
elseif string.find(entry.value.remotehost.value, "[^%w.-]") then
entry.value.remotehost.errtxt = "Invalid entry - may only contain alphanumeric, '.', or '-'"
success = false
end
if entry.value.remotemailbox.value == "" then
entry.value.remotemailbox.errtxt = "Invalid entry - cannot be blank"
success = false
elseif string.find(entry.value.remotemailbox.value, "[^%w.-_@]") then
entry.value.remotemailbox.errtxt = "Invalid entry"
success = false
end
if entry.value.remotepassword.value == "" then
entry.value.remotepassword.errtxt = "Invalid entry - cannot be blank"
success = false
elseif string.find(entry.value.remotepassword.value, "%s") then
entry.value.remotepassword.errtxt = "Invalid entry - cannot contain whitespace"
success = false
end
if entry.value.localhost.value == "" then
entry.value.localhost.errtxt = "Invalid entry - cannot be blank"
success = false
elseif string.find(entry.value.localhost.value, "[^%w.-]") then
entry.value.localhost.errtxt = "Invalid entry - may only contain alphanumeric, '.', or '-'"
success = false
end
if entry.value.method.value == "pop3domain" and entry.value.localmailbox.value ~= "" then
entry.value.localmailbox.errtxt = "Cannot define local mailbox for pop3domain method"
success = false