diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-08 21:01:45 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-08 21:01:45 +0000 |
| commit | 5b2a124305f26d36e95b639b1c70a32368f03261 (patch) | |
| tree | 6b34fb2c047b2b88cea89b2b3aa87f546fef726d /src/smtp.lua | |
| parent | 60e7bf48b077377c11022f34e24bbbfb596397bf (diff) | |
| download | luasocket-5b2a124305f26d36e95b639b1c70a32368f03261.tar.gz luasocket-5b2a124305f26d36e95b639b1c70a32368f03261.tar.bz2 luasocket-5b2a124305f26d36e95b639b1c70a32368f03261.zip | |
Updated for Lua 4.1-w3.
Diffstat (limited to 'src/smtp.lua')
| -rw-r--r-- | src/smtp.lua | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/src/smtp.lua b/src/smtp.lua index 7450792..72a0e5a 100644 --- a/src/smtp.lua +++ b/src/smtp.lua | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
| 2 | -- SMTP support for the Lua language. | 2 | -- SMTP support for the Lua language. |
| 3 | -- LuaSocket 1.4 toolkit | 3 | -- LuaSocket 1.5 toolkit |
| 4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
| 5 | -- Date: 26/12/2000 | 5 | -- Date: 26/12/2000 |
| 6 | -- Conforming to: RFC 821, LTN7 | 6 | -- Conforming to: RFC 821, LTN7 |
| @@ -65,7 +65,7 @@ function Private.send_command(sock, command, param) | |||
| 65 | local line | 65 | local line |
| 66 | if param then line = command .. " " .. param .. "\r\n" | 66 | if param then line = command .. " " .. param .. "\r\n" |
| 67 | else line = command .. "\r\n" end | 67 | else line = command .. "\r\n" end |
| 68 | return %Private.try_send(sock, line) | 68 | return Private.try_send(sock, line) |
| 69 | end | 69 | end |
| 70 | 70 | ||
| 71 | ----------------------------------------------------------------------------- | 71 | ----------------------------------------------------------------------------- |
| @@ -78,14 +78,14 @@ end | |||
| 78 | ----------------------------------------------------------------------------- | 78 | ----------------------------------------------------------------------------- |
| 79 | function Private.get_answer(control) | 79 | function Private.get_answer(control) |
| 80 | local code, lastcode, sep, _ | 80 | local code, lastcode, sep, _ |
| 81 | local line, err = %Private.try_receive(control) | 81 | local line, err = Private.try_receive(control) |
| 82 | local answer = line | 82 | local answer = line |
| 83 | if err then return nil, err end | 83 | if err then return nil, err end |
| 84 | _,_, code, sep = strfind(line, "^(%d%d%d)(.)") | 84 | _,_, code, sep = strfind(line, "^(%d%d%d)(.)") |
| 85 | if not code or not sep then return nil, answer end | 85 | if not code or not sep then return nil, answer end |
| 86 | if sep == "-" then -- answer is multiline | 86 | if sep == "-" then -- answer is multiline |
| 87 | repeat | 87 | repeat |
| 88 | line, err = %Private.try_receive(control) | 88 | line, err = Private.try_receive(control) |
| 89 | if err then return nil, err end | 89 | if err then return nil, err end |
| 90 | _,_, lastcode, sep = strfind(line, "^(%d%d%d)(.)") | 90 | _,_, lastcode, sep = strfind(line, "^(%d%d%d)(.)") |
| 91 | answer = answer .. "\n" .. line | 91 | answer = answer .. "\n" .. line |
| @@ -105,7 +105,7 @@ end | |||
| 105 | -- answer: complete server answer or system error message | 105 | -- answer: complete server answer or system error message |
| 106 | ----------------------------------------------------------------------------- | 106 | ----------------------------------------------------------------------------- |
| 107 | function Private.check_answer(control, success) | 107 | function Private.check_answer(control, success) |
| 108 | local answer, code = %Private.get_answer(control) | 108 | local answer, code = Private.get_answer(control) |
| 109 | if not answer then return nil, code end | 109 | if not answer then return nil, code end |
| 110 | if type(success) ~= "table" then success = {success} end | 110 | if type(success) ~= "table" then success = {success} end |
| 111 | for i = 1, getn(success) do | 111 | for i = 1, getn(success) do |
| @@ -126,9 +126,9 @@ end | |||
| 126 | -- answer: complete server reply | 126 | -- answer: complete server reply |
| 127 | ----------------------------------------------------------------------------- | 127 | ----------------------------------------------------------------------------- |
| 128 | function Private.send_helo(sock) | 128 | function Private.send_helo(sock) |
| 129 | local err = %Private.send_command(sock, "HELO", %Public.DOMAIN) | 129 | local err = Private.send_command(sock, "HELO", Public.DOMAIN) |
| 130 | if err then return nil, err end | 130 | if err then return nil, err end |
| 131 | return %Private.check_answer(sock, 250) | 131 | return Private.check_answer(sock, 250) |
| 132 | end | 132 | end |
| 133 | 133 | ||
| 134 | ----------------------------------------------------------------------------- | 134 | ----------------------------------------------------------------------------- |
| @@ -140,9 +140,9 @@ end | |||
| 140 | -- answer: complete server reply or error message | 140 | -- answer: complete server reply or error message |
| 141 | ----------------------------------------------------------------------------- | 141 | ----------------------------------------------------------------------------- |
| 142 | function Private.send_quit(sock) | 142 | function Private.send_quit(sock) |
| 143 | local err = %Private.send_command(sock, "QUIT") | 143 | local err = Private.send_command(sock, "QUIT") |
| 144 | if err then return nil, err end | 144 | if err then return nil, err end |
| 145 | local code, answer = %Private.check_answer(sock, 221) | 145 | local code, answer = Private.check_answer(sock, 221) |
| 146 | sock:close() | 146 | sock:close() |
| 147 | return code, answer | 147 | return code, answer |
| 148 | end | 148 | end |
| @@ -158,9 +158,9 @@ end | |||
| 158 | ----------------------------------------------------------------------------- | 158 | ----------------------------------------------------------------------------- |
| 159 | function Private.send_mail(sock, sender) | 159 | function Private.send_mail(sock, sender) |
| 160 | local param = format("FROM:<%s>", sender or "") | 160 | local param = format("FROM:<%s>", sender or "") |
| 161 | local err = %Private.send_command(sock, "MAIL", param) | 161 | local err = Private.send_command(sock, "MAIL", param) |
| 162 | if err then return nil, err end | 162 | if err then return nil, err end |
| 163 | return %Private.check_answer(sock, 250) | 163 | return Private.check_answer(sock, 250) |
| 164 | end | 164 | end |
| 165 | 165 | ||
| 166 | ----------------------------------------------------------------------------- | 166 | ----------------------------------------------------------------------------- |
| @@ -175,11 +175,11 @@ function Private.send_headers(sock, headers) | |||
| 175 | local err | 175 | local err |
| 176 | -- send request headers | 176 | -- send request headers |
| 177 | for i, v in headers or {} do | 177 | for i, v in headers or {} do |
| 178 | err = %Private.try_send(sock, i .. ": " .. v .. "\r\n") | 178 | err = Private.try_send(sock, i .. ": " .. v .. "\r\n") |
| 179 | if err then return err end | 179 | if err then return err end |
| 180 | end | 180 | end |
| 181 | -- mark end of request headers | 181 | -- mark end of request headers |
| 182 | return %Private.try_send(sock, "\r\n") | 182 | return Private.try_send(sock, "\r\n") |
| 183 | end | 183 | end |
| 184 | 184 | ||
| 185 | ----------------------------------------------------------------------------- | 185 | ----------------------------------------------------------------------------- |
| @@ -193,18 +193,18 @@ end | |||
| 193 | -- answer: complete server reply or error message | 193 | -- answer: complete server reply or error message |
| 194 | ----------------------------------------------------------------------------- | 194 | ----------------------------------------------------------------------------- |
| 195 | function Private.send_data(sock, headers, body) | 195 | function Private.send_data(sock, headers, body) |
| 196 | local err = %Private.send_command(sock, "DATA") | 196 | local err = Private.send_command(sock, "DATA") |
| 197 | if err then return nil, err end | 197 | if err then return nil, err end |
| 198 | local code, answer = %Private.check_answer(sock, 354) | 198 | local code, answer = Private.check_answer(sock, 354) |
| 199 | if not code then return nil, answer end | 199 | if not code then return nil, answer end |
| 200 | -- avoid premature end in message body | 200 | -- avoid premature end in message body |
| 201 | body = gsub(body or "", "\n%.", "\n%.%.") | 201 | body = gsub(body or "", "\n%.", "\n%.%.") |
| 202 | -- mark end of message body | 202 | -- mark end of message body |
| 203 | body = body .. "\r\n.\r\n" | 203 | body = body .. "\r\n.\r\n" |
| 204 | err = %Private.send_headers(sock, headers) | 204 | err = Private.send_headers(sock, headers) |
| 205 | if err then return nil, err end | 205 | if err then return nil, err end |
| 206 | err = %Private.try_send(sock, body) | 206 | err = Private.try_send(sock, body) |
| 207 | return %Private.check_answer(sock, 250) | 207 | return Private.check_answer(sock, 250) |
| 208 | end | 208 | end |
| 209 | 209 | ||
| 210 | ----------------------------------------------------------------------------- | 210 | ----------------------------------------------------------------------------- |
| @@ -221,9 +221,9 @@ function Private.send_rcpt(sock, rcpt) | |||
| 221 | local code, answer = nil, "No recipient specified" | 221 | local code, answer = nil, "No recipient specified" |
| 222 | if type(rcpt) ~= "table" then rcpt = {rcpt} end | 222 | if type(rcpt) ~= "table" then rcpt = {rcpt} end |
| 223 | for i = 1, getn(rcpt) do | 223 | for i = 1, getn(rcpt) do |
| 224 | err = %Private.send_command(sock, "RCPT", format("TO:<%s>", rcpt[i])) | 224 | err = Private.send_command(sock, "RCPT", format("TO:<%s>", rcpt[i])) |
| 225 | if err then return nil, err end | 225 | if err then return nil, err end |
| 226 | code, answer = %Private.check_answer(sock, {250, 251}) | 226 | code, answer = Private.check_answer(sock, {250, 251}) |
| 227 | if not code then return code, answer end | 227 | if not code then return code, answer end |
| 228 | end | 228 | end |
| 229 | return code, answer | 229 | return code, answer |
| @@ -240,16 +240,16 @@ end | |||
| 240 | function Private.open(server) | 240 | function Private.open(server) |
| 241 | local code, answer | 241 | local code, answer |
| 242 | -- default server | 242 | -- default server |
| 243 | server = server or %Public.SERVER | 243 | server = server or Public.SERVER |
| 244 | -- connect to server and make sure we won't hang | 244 | -- connect to server and make sure we won't hang |
| 245 | local sock, err = connect(server, %Public.PORT) | 245 | local sock, err = connect(server, Public.PORT) |
| 246 | if not sock then return nil, err end | 246 | if not sock then return nil, err end |
| 247 | sock:timeout(%Public.TIMEOUT) | 247 | sock:timeout(Public.TIMEOUT) |
| 248 | -- initial server greeting | 248 | -- initial server greeting |
| 249 | code, answer = %Private.check_answer(sock, 220) | 249 | code, answer = Private.check_answer(sock, 220) |
| 250 | if not code then return nil, answer end | 250 | if not code then return nil, answer end |
| 251 | -- HELO | 251 | -- HELO |
| 252 | code, answer = %Private.send_helo(sock) | 252 | code, answer = Private.send_helo(sock) |
| 253 | if not code then return nil, answer end | 253 | if not code then return nil, answer end |
| 254 | return sock | 254 | return sock |
| 255 | end | 255 | end |
| @@ -270,13 +270,13 @@ end | |||
| 270 | function Private.send(sock, message) | 270 | function Private.send(sock, message) |
| 271 | local code, answer | 271 | local code, answer |
| 272 | 272 | ||
| 273 | code, answer = %Private.send_mail(sock, message.from) | 273 | code, answer = Private.send_mail(sock, message.from) |
| 274 | if not code then return nil, answer end | 274 | if not code then return nil, answer end |
| 275 | -- RCPT | 275 | -- RCPT |
| 276 | code, answer = %Private.send_rcpt(sock, message.rcpt) | 276 | code, answer = Private.send_rcpt(sock, message.rcpt) |
| 277 | if not code then return nil, answer end | 277 | if not code then return nil, answer end |
| 278 | -- DATA | 278 | -- DATA |
| 279 | return %Private.send_data(sock, message.headers, message.body) | 279 | return Private.send_data(sock, message.headers, message.body) |
| 280 | end | 280 | end |
| 281 | 281 | ||
| 282 | ----------------------------------------------------------------------------- | 282 | ----------------------------------------------------------------------------- |
| @@ -289,7 +289,7 @@ end | |||
| 289 | ----------------------------------------------------------------------------- | 289 | ----------------------------------------------------------------------------- |
| 290 | function Private.close(sock) | 290 | function Private.close(sock) |
| 291 | -- QUIT | 291 | -- QUIT |
| 292 | return %Private.send_quit(sock) | 292 | return Private.send_quit(sock) |
| 293 | end | 293 | end |
| 294 | 294 | ||
| 295 | ----------------------------------------------------------------------------- | 295 | ----------------------------------------------------------------------------- |
| @@ -305,11 +305,11 @@ end | |||
| 305 | -- nil if successfull, error message in case of error | 305 | -- nil if successfull, error message in case of error |
| 306 | ----------------------------------------------------------------------------- | 306 | ----------------------------------------------------------------------------- |
| 307 | function Public.mail(message) | 307 | function Public.mail(message) |
| 308 | local sock, err = %Private.open(message.server) | 308 | local sock, err = Private.open(message.server) |
| 309 | if not sock then return err end | 309 | if not sock then return err end |
| 310 | local code, answer = %Private.send(sock, message) | 310 | local code, answer = Private.send(sock, message) |
| 311 | if not code then return answer end | 311 | if not code then return answer end |
| 312 | code, answer = %Private.close(sock) | 312 | code, answer = Private.close(sock) |
| 313 | if code then return nil end | 313 | if code then return nil end |
| 314 | return answer | 314 | return answer |
| 315 | end | 315 | end |
