123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- os = require "os"
- socket = require "socket"
-
-
- ------------------------------------------------------------------------------
- -- config and handling --
- ------------------------------------------------------------------------------
-
- function shortname()
- --
- -- Short hostname
- --
- local long = socket.dns.gethostname()
- return string.gmatch(long, '[^.]+')()
- end
-
- function file_exists(name)
- --
- -- True if file *name* exists
- --
- local f = io.open(name,"r")
- if f ~= nil then
- io.close(f)
- return true
- else
- return false
- end
- end
-
- function init_host(session)
- --
- -- Do host-specific init, if exists
- --
- local init = session.dirs.host .. "/init.lua"
- if file_exists(init) then
- dofile(init)
- return
- end
- end
-
- function handle(session)
- --
- -- Look for action handler in session dirs; do first one that exists
- --
- local valid = {
- newmail = true,
- rewind = true,
- cleanup = true,
- migrate = true
- }
- if not valid[session.action] then
- error("invalid action: " .. session.action)
- return nil
- end
- init_host(session)
- for k,v in ipairs({session.dirs.host, session.dirs.default}) do
- attempt = v .. "/handlers/" .. session.action .. ".lua"
- if file_exists(attempt) then
- dofile(attempt)
- return
- end
- end
- end
-
-
- ------------------------------------------------------------------------------
- -- mail getters --
- ------------------------------------------------------------------------------
-
- function get_queue(acct, mbox)
- --
- -- Get queue from *mbox* from *acct* or nil (no messages)
- --
- -- If mbox is not specified, "FILTER_QUEUE" is used
- --
- mbox = mbox or "FILTER_QUEUE"
- local exist, unread, unseen, uidnext = acct[mbox]:check_status()
- if exist > 0 then
- return acct[mbox]:select_all()
- end
- return nil
- end
-
- function _notifirc1(subj, from, body)
- --
- -- notify about message using (pre-configured) notifirc
- --
- local fd = assert(io.popen('notifirc -c mail -f - "message preview:"', "w"))
- local fmt = "> %s\n> %s\n> BODY: %s"
- fd:write(fmt:format(subj, from, body))
- fd:close()
- end
-
- function notifirc_all(seq)
- --
- -- Send notifications about all messages in *seq*
- --
- for _, mesg in ipairs(seq) do
- mbox, uid = table.unpack(mesg)
- subj = mbox[uid]:fetch_field('Subject')
- from = mbox[uid]:fetch_field('From')
- body = mbox[uid]:fetch_body()
- _notifirc1(subj, from, body)
- end
- end
-
- function _partinf_compare(a, b)
- if not type(a) == type(b) then
- return false
- end
- if type(a) == 'number' then
- return a == b
- elseif type(a) == 'string' then
- return a:lower() == b:lower()
- end
- end
-
- function has_part_like(query, structure)
- --
- -- True if structure has MIME part matching *query*
- --
- if structure == nil then
- return false
- end
- for partid, partinf in pairs(structure) do
- local part_answer = true
- -- check all query parts
- for qkey, qvalue in pairs(query) do
- value = partinf[qkey]
- if not _partinf_compare(value, qvalue) then
- part_answer = false
- break
- end
- end
- if part_answer then
- return true
- end
- end
- return false
- end
-
- function save_header(mesg, name)
- --
- -- Append header from *mesg* to file named *name*
- --
- -- File will be placed under directory specified by IMAPDOMO_HEADERS
- -- environment variable.
- --
- local dest = os.getenv("IMAPDOMO_HEADERS") .. '/' .. name
- local cmd = ('cat >>"%q"'):format(dest)
- mbox, uid = table.unpack(mesg)
- header = mbox[uid]:fetch_header()
- if pipe_to(cmd, header) == 0 then
- return true
- else
- return false
- end
- end
-
- function filter_header_saved(seq, name)
- --
- -- Save headers from sequence
- --
- -- Append header of each message in sequence *seq* to file names
- -- *name* and return new sequence with those messages where save was
- -- successful.
- --
- result = Set {}
- for _, mesg in ipairs(seq) do
- if save_header(mesg, name) then
- table.insert(result, mesg)
- end
- end
- return result
- end
-
- function filter_part_like(query, seq)
- --
- -- Run MIME part query on *seq* sequence of messages
- --
- result = Set {}
- for _, mesg in ipairs(seq) do
- mbox, uid = table.unpack(mesg)
- structure = mbox[uid]:fetch_structure()
- if has_part_like(query, structure) then
- table.insert(result, mesg)
- end
- end
- return result
- end
|