Still work to do in the manual...
This commit is contained in:
parent
8e80e38f2c
commit
0a4c1534f3
15 changed files with 257 additions and 146 deletions
|
@ -23,6 +23,7 @@ BLOCKSIZE = 2048
|
|||
-----------------------------------------------------------------------------
|
||||
-- returns a high level filter that cycles a low-level filter
|
||||
function filter.cycle(low, ctx, extra)
|
||||
assert(low)
|
||||
return function(chunk)
|
||||
local ret
|
||||
ret, ctx = low(ctx, chunk, extra)
|
||||
|
@ -32,6 +33,7 @@ end
|
|||
|
||||
-- chains two filters together
|
||||
local function chain2(f1, f2)
|
||||
assert(f1 and f2)
|
||||
local co = coroutine.create(function(chunk)
|
||||
while true do
|
||||
local filtered1 = f1(chunk)
|
||||
|
@ -95,6 +97,7 @@ end
|
|||
|
||||
-- turns a fancy source into a simple source
|
||||
function source.simplify(src)
|
||||
assert(src)
|
||||
return function()
|
||||
local chunk, err_or_new = src()
|
||||
src = err_or_new or src
|
||||
|
@ -118,6 +121,7 @@ end
|
|||
|
||||
-- creates rewindable source
|
||||
function source.rewind(src)
|
||||
assert(src)
|
||||
local t = {}
|
||||
return function(chunk)
|
||||
if not chunk then
|
||||
|
@ -132,6 +136,7 @@ end
|
|||
|
||||
-- chains a source with a filter
|
||||
function source.chain(src, f)
|
||||
assert(src and f)
|
||||
local co = coroutine.create(function()
|
||||
while true do
|
||||
local chunk, err = src()
|
||||
|
@ -186,6 +191,7 @@ end
|
|||
|
||||
-- turns a fancy sink into a simple sink
|
||||
function sink.simplify(snk)
|
||||
assert(snk)
|
||||
return function(chunk, err)
|
||||
local ret, err_or_new = snk(chunk, err)
|
||||
if not ret then return nil, err_or_new end
|
||||
|
@ -224,6 +230,7 @@ end
|
|||
|
||||
-- chains a sink with a filter
|
||||
function sink.chain(f, snk)
|
||||
assert(f and snk)
|
||||
return function(chunk, err)
|
||||
local filtered = f(chunk)
|
||||
local done = chunk and ""
|
||||
|
@ -248,6 +255,7 @@ end
|
|||
|
||||
-- pumps all data from a source to a sink, using a step function
|
||||
function pump.all(src, snk, step)
|
||||
assert(src and snk)
|
||||
step = step or pump.step
|
||||
while true do
|
||||
local ret, err = step(src, snk)
|
||||
|
|
33
src/smtp.lua
33
src/smtp.lua
|
@ -11,6 +11,7 @@
|
|||
local smtp = requirelib("smtp", "luaopen_smtp", getfenv(1))
|
||||
local socket = require("socket")
|
||||
local ltn12 = require("ltn12")
|
||||
local mime = require("mime")
|
||||
local tp = require("tp")
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
@ -43,7 +44,7 @@ local metat = { __index = {} }
|
|||
function metat.__index:greet(domain)
|
||||
socket.try(self.tp:check("2.."))
|
||||
socket.try(self.tp:command("EHLO", domain or DOMAIN))
|
||||
return socket.try(self.tp:check("2.."))
|
||||
return socket.skip(1, socket.try(self.tp:check("2..")))
|
||||
end
|
||||
|
||||
function metat.__index:mail(from)
|
||||
|
@ -73,6 +74,32 @@ function metat.__index:close()
|
|||
return socket.try(self.tp:close())
|
||||
end
|
||||
|
||||
function metat.__index:login(user, password)
|
||||
socket.try(self.tp:command("AUTH", "LOGIN"))
|
||||
socket.try(self.tp:check("3.."))
|
||||
socket.try(self.tp:command(mime.b64(user)))
|
||||
socket.try(self.tp:check("3.."))
|
||||
socket.try(self.tp:command(mime.b64(password)))
|
||||
return socket.try(self.tp:check("2.."))
|
||||
end
|
||||
|
||||
function metat.__index:plain(user, password)
|
||||
local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
|
||||
socket.try(self.tp:command("AUTH", auth))
|
||||
return socket.try(self.tp:check("2.."))
|
||||
end
|
||||
|
||||
function metat.__index:auth(user, password, ext)
|
||||
if not user or not password then return 1 end
|
||||
if string.find(ext, "AUTH[^\n]+LOGIN") then
|
||||
return self:login(user, password)
|
||||
elseif string.find(ext, "AUTH[^\n]+PLAIN") then
|
||||
return self:plain(user, password)
|
||||
else
|
||||
socket.try(nil, "authentication not supported")
|
||||
end
|
||||
end
|
||||
|
||||
-- send message or throw an exception
|
||||
function metat.__index:send(mailt)
|
||||
self:mail(mailt.from)
|
||||
|
@ -205,10 +232,10 @@ end
|
|||
---------------------------------------------------------------------------
|
||||
-- High level SMTP API
|
||||
-----------------------------------------------------------------------------
|
||||
socket.protect = function(a) return a end
|
||||
send = socket.protect(function(mailt)
|
||||
local con = open(mailt.server, mailt.port)
|
||||
con:greet(mailt.domain)
|
||||
local ext = con:greet(mailt.domain)
|
||||
con:auth(mailt.user, mailt.password, ext)
|
||||
con:send(mailt)
|
||||
con:quit()
|
||||
return con:close()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue