From 9e02348aaa369221b8d65c5ba1965aa39dc28131 Mon Sep 17 00:00:00 2001 From: ttrask Date: Thu, 19 Mar 2009 15:58:10 +0000 Subject: Modified fetchmail to put 'is' at the end and change parsing of lines to try to distinguish better between keywords and parameters. git-svn-id: svn://svn.alpinelinux.org/acf/fetchmail/trunk@1736 ab2d0c66-481e-0410-8bed-d214d4d58bed --- fetchmail-model.lua | 60 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/fetchmail-model.lua b/fetchmail-model.lua index 8cb0cc0..f105ba9 100644 --- a/fetchmail-model.lua +++ b/fetchmail-model.lua @@ -19,6 +19,30 @@ local methods = {"pop3","imap","pop3domain", "etrn", } -- ################################################################################ -- LOCAL FUNCTIONS +local function findkeywordsinentry(entry) + local reverseentry = {} + -- we can't just do a simple reverse table in case keywords are used as parameters (ie. password = password) + --for i,word in ipairs(entry) do reverseentry[word] = i end + -- so, have to parse word by word + -- the following is a list of the keywords we know about in this ACF + -- dns, fetchall, fetchdomains, is, local, localdomains, pass, password, proto, protocol, rewrite, smtphost, ssl, user, username + -- array of keywords that take one parameter (don't know how to handle multiple domains) + local keywords = { "fetchdomains", "is", "local", "localdomains", "pass", "password", "proto", "protocol", "smtphost", "user", "username" } + local reversekeywords = {} + for i,word in ipairs(keywords) do reversekeywords[word] = i end + + local i=0 + while i<#entry do + i = i+1 + reverseentry[entry[i]] = i + if reversekeywords[entry[i]] then + i = i+1 + end + end + + return reverseentry +end + local function parseconfigfile(file) file = file or "" local retval = {} @@ -51,20 +75,22 @@ local function findentryline(entryname, method, remotemailbox, localdomain) config = config or parseconfigfile(fs.read_file(configfile) or "") 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 - local reverseentry = {} - for i,word in ipairs(entry) do reverseentry[word] = i end + local reverseentry = findkeywordsinentry(entry) -- For pop3domain, check the localdomain if method == "pop3domain" and (reverseentry["local"] or reverseentry["localdomains"]) then if entry[(reverseentry["local"] or reverseentry["localdomains"])+1] == localdomain then return entry end - -- For etrn, no further check - elseif method == "etrn" and reverseentry["etrn"] then - return entry - -- For pop3 and imap, check the username - elseif method == "pop3" or method == "imap" then - if reverseentry["username"] and entry[reverseentry["username"]+1] == remotemailbox then + elseif reverseentry["proto"] or reverseentry["protocol"] then + local protocol = entry[(reverseentry["proto"] or reverseentry["protocol"])+1] + -- For etrn, no further check + if method == "etrn" and protocol == "etrn" then return entry + -- For pop3 and imap, check the username + elseif protocol == method and (method == "pop3" or method == "imap") then + if reverseentry["username"] and entry[reverseentry["username"]+1] == remotemailbox then + return entry + end end end end @@ -82,8 +108,7 @@ local function writeentryline(entrystruct, entryline) if entrystruct then entryline = entryline or {} insertentries = {} - local reverseentry = {} - for i,word in ipairs(entryline) do reverseentry[word] = i end + local reverseentry = findkeywordsinentry(entryline) -- Server options must come before user options, so add user option to end -- and add server options just after remotehost (3). To do this, we'll use an array -- of insertentries that will be inserted at the end. To delete entries, just set @@ -147,21 +172,18 @@ local function writeentryline(entrystruct, entryline) if entrystruct.value.method.value == "pop3domain" then setserveroption("protocol", "pop3") setserveroption("localdomains", entrystruct.value.localdomain.value) - deleteoptionandvalue("is") setuseroption("to", "*") setuseroption("smtpaddress", entrystruct.value.localdomain.value) deleteoptionandvalue("fetchdomains") elseif entrystruct.value.method.value == "etrn" then setserveroption("protocol", entrystruct.value.method.value) deleteoptionandvalue("localdomains") - deleteoptionandvalue("is") deleteoptionandvalue("to") deleteoptionandvalue("smtpaddress") setuseroption("fetchdomains", entrystruct.value.localdomain.value) else -- Method not pop3domain or etrn setserveroption("protocol", entrystruct.value.method.value) deleteoptionandvalue("localdomains") - setuseroption("is", entrystruct.value.localmailbox.value) deleteoptionandvalue("to") deleteoptionandvalue("smtpaddress") deleteoptionandvalue("fetchdomains") @@ -195,6 +217,12 @@ local function writeentryline(entrystruct, entryline) entryline[reverseentry["ssl"]] = nil end end + -- for some reason, the "is" option has to come after username/password + if entrystruct.value.method.value == "pop3domain" or entrystruct.value.method.value == "etrn" then + deleteoptionandvalue("is") + else + setuseroption("is", entrystruct.value.localmailbox.value) + end -- Now, insert the insertentries and remove the nil entries table.insert(insertentries, 1, entryline[1]) @@ -408,8 +436,7 @@ function readentries() config = config or parseconfigfile(fs.read_file(configfile) or "") for i,entry in ipairs(config or {}) do if (entry[1] == "server" or entry[1] == "poll" or entry[1] == "skip") and entry[2] then - local reverseentry = {} - for i,word in ipairs(entry) do reverseentry[word] = i end + local reverseentry = findkeywordsinentry(entry) local method = "error" local localdomain = "" if reverseentry["local"] or reverseentry["localdomains"] then @@ -448,8 +475,7 @@ function readentry(entryname, meth, remotemailbx, localdom) if entry[1] == "skip" then enabled.value = false end - local reverseentry = {} - for i,word in ipairs(entry) do reverseentry[word] = i end + local reverseentry = findkeywordsinentry(entry) if reverseentry["local"] or reverseentry["localdomains"] then localdomain.value = entry[(reverseentry["local"] or reverseentry["localdomains"])+1] or localdomain.value method.value = "pop3domain" -- cgit v1.2.3