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() -- -- Look for action handler in basepaths; do first one -- local init = imapdomo.dirs.host .. "/init.lua" if file_exists(init) then dofile(init) return end end function handle(action, basepaths) -- -- Look for action handler in basepaths; do first one -- local valid = { newmail = true, rewind = true, cleanup = true, migrate = true } if not valid[action] then error("invalid action: " .. action) return nil end init_host() for k,v in ipairs({imapdomo.dirs.host, imapdomo.dirs.default}) do attempt = v .. "/handlers/" .. 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 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