aboutsummaryrefslogtreecommitdiff
path: root/src/smtp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/smtp.lua')
-rw-r--r--src/smtp.lua43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/smtp.lua b/src/smtp.lua
index c823c97..ed8bd15 100644
--- a/src/smtp.lua
+++ b/src/smtp.lua
@@ -20,16 +20,17 @@ DOMAIN = os.getenv("SERVER_NAME") or "localhost"
20-- default time zone (means we don't know) 20-- default time zone (means we don't know)
21ZONE = "-0000" 21ZONE = "-0000"
22 22
23function stuff()
24 return ltn12.filter.cycle(dot, 2)
25end
26
27local function shift(a, b, c) 23local function shift(a, b, c)
28 return b, c 24 return b, c
29end 25end
30 26
27-- high level stuffing filter
28function stuff()
29 return ltn12.filter.cycle(dot, 2)
30end
31
31-- send message or throw an exception 32-- send message or throw an exception
32function psend(control, mailt) 33local function send_p(control, mailt)
33 socket.try(control:check("2..")) 34 socket.try(control:check("2.."))
34 socket.try(control:command("EHLO", mailt.domain or DOMAIN)) 35 socket.try(control:command("EHLO", mailt.domain or DOMAIN))
35 socket.try(control:check("2..")) 36 socket.try(control:check("2.."))
@@ -61,11 +62,11 @@ local function newboundary()
61 math.random(0, 99999), seqno) 62 math.random(0, 99999), seqno)
62end 63end
63 64
64-- sendmessage forward declaration 65-- send_message forward declaration
65local sendmessage 66local send_message
66 67
67-- yield multipart message body from a multipart message table 68-- yield multipart message body from a multipart message table
68local function sendmultipart(mesgt) 69local function send_multipart(mesgt)
69 local bd = newboundary() 70 local bd = newboundary()
70 -- define boundary and finish headers 71 -- define boundary and finish headers
71 coroutine.yield('content-type: multipart/mixed; boundary="' .. 72 coroutine.yield('content-type: multipart/mixed; boundary="' ..
@@ -75,7 +76,7 @@ local function sendmultipart(mesgt)
75 -- send each part separated by a boundary 76 -- send each part separated by a boundary
76 for i, m in ipairs(mesgt.body) do 77 for i, m in ipairs(mesgt.body) do
77 coroutine.yield("\r\n--" .. bd .. "\r\n") 78 coroutine.yield("\r\n--" .. bd .. "\r\n")
78 sendmessage(m) 79 send_message(m)
79 end 80 end
80 -- send last boundary 81 -- send last boundary
81 coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n") 82 coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
@@ -84,7 +85,7 @@ local function sendmultipart(mesgt)
84end 85end
85 86
86-- yield message body from a source 87-- yield message body from a source
87local function sendsource(mesgt) 88local function send_source(mesgt)
88 -- set content-type if user didn't override 89 -- set content-type if user didn't override
89 if not mesgt.headers or not mesgt.headers["content-type"] then 90 if not mesgt.headers or not mesgt.headers["content-type"] then
90 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n') 91 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
@@ -101,7 +102,7 @@ local function sendsource(mesgt)
101end 102end
102 103
103-- yield message body from a string 104-- yield message body from a string
104local function sendstring(mesgt) 105local function send_string(mesgt)
105 -- set content-type if user didn't override 106 -- set content-type if user didn't override
106 if not mesgt.headers or not mesgt.headers["content-type"] then 107 if not mesgt.headers or not mesgt.headers["content-type"] then
107 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n') 108 coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
@@ -114,7 +115,7 @@ local function sendstring(mesgt)
114end 115end
115 116
116-- yield the headers one by one 117-- yield the headers one by one
117local function sendheaders(mesgt) 118local function send_headers(mesgt)
118 if mesgt.headers then 119 if mesgt.headers then
119 for i,v in pairs(mesgt.headers) do 120 for i,v in pairs(mesgt.headers) do
120 coroutine.yield(i .. ':' .. v .. "\r\n") 121 coroutine.yield(i .. ':' .. v .. "\r\n")
@@ -123,15 +124,15 @@ local function sendheaders(mesgt)
123end 124end
124 125
125-- message source 126-- message source
126function sendmessage(mesgt) 127function send_message(mesgt)
127 sendheaders(mesgt) 128 send_headers(mesgt)
128 if type(mesgt.body) == "table" then sendmultipart(mesgt) 129 if type(mesgt.body) == "table" then send_multipart(mesgt)
129 elseif type(mesgt.body) == "function" then sendsource(mesgt) 130 elseif type(mesgt.body) == "function" then send_source(mesgt)
130 else sendstring(mesgt) end 131 else send_string(mesgt) end
131end 132end
132 133
133-- set defaul headers 134-- set defaul headers
134local function adjustheaders(mesgt) 135local function adjust_headers(mesgt)
135 mesgt.headers = mesgt.headers or {} 136 mesgt.headers = mesgt.headers or {}
136 mesgt.headers["mime-version"] = "1.0" 137 mesgt.headers["mime-version"] = "1.0"
137 mesgt.headers["date"] = mesgt.headers["date"] or 138 mesgt.headers["date"] = mesgt.headers["date"] or
@@ -140,16 +141,16 @@ local function adjustheaders(mesgt)
140end 141end
141 142
142function message(mesgt) 143function message(mesgt)
143 adjustheaders(mesgt) 144 adjust_headers(mesgt)
144 -- create and return message source 145 -- create and return message source
145 local co = coroutine.create(function() sendmessage(mesgt) end) 146 local co = coroutine.create(function() send_message(mesgt) end)
146 return function() return shift(coroutine.resume(co)) end 147 return function() return shift(coroutine.resume(co)) end
147end 148end
148 149
149function send(mailt) 150function send(mailt)
150 local c, e = socket.tp.connect(mailt.server or SERVER, mailt.port or PORT) 151 local c, e = socket.tp.connect(mailt.server or SERVER, mailt.port or PORT)
151 if not c then return nil, e end 152 if not c then return nil, e end
152 local s, e = pcall(psend, c, mailt) 153 local s, e = pcall(send_p, c, mailt)
153 c:close() 154 c:close()
154 if s then return true 155 if s then return true
155 else return nil, e end 156 else return nil, e end