diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-03-18 07:01:14 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-03-18 07:01:14 +0000 |
commit | 2c160627e51650f98d6ef01ae36bb86d6e91045f (patch) | |
tree | e67051e051b0a315aebc0a511d242905272aecfb /src/tp.lua | |
parent | bcc0c2a9f0be2ca796ef5206a78e283fe15e6186 (diff) | |
download | luasocket-2c160627e51650f98d6ef01ae36bb86d6e91045f.tar.gz luasocket-2c160627e51650f98d6ef01ae36bb86d6e91045f.tar.bz2 luasocket-2c160627e51650f98d6ef01ae36bb86d6e91045f.zip |
Message source in smtp.lua is a work of art.
Diffstat (limited to 'src/tp.lua')
-rw-r--r-- | src/tp.lua | 54 |
1 files changed, 22 insertions, 32 deletions
@@ -18,32 +18,18 @@ setfenv(1, socket.tp) | |||
18 | 18 | ||
19 | TIMEOUT = 60 | 19 | TIMEOUT = 60 |
20 | 20 | ||
21 | -- tries to get a pattern from the server and closes socket on error | ||
22 | local function try_receiving(sock, pattern) | ||
23 | local data, message = sock:receive(pattern) | ||
24 | if not data then sock:close() end | ||
25 | return data, message | ||
26 | end | ||
27 | |||
28 | -- tries to send data to server and closes socket on error | ||
29 | local function try_sending(sock, data) | ||
30 | local sent, message = sock:send(data) | ||
31 | if not sent then sock:close() end | ||
32 | return sent, message | ||
33 | end | ||
34 | |||
35 | -- gets server reply | 21 | -- gets server reply |
36 | local function get_reply(sock) | 22 | local function get_reply(sock) |
37 | local code, current, separator, _ | 23 | local code, current, separator, _ |
38 | local line, message = try_receiving(sock) | 24 | local line, err = sock:receive() |
39 | local reply = line | 25 | local reply = line |
40 | if message then return nil, message end | 26 | if err then return nil, err end |
41 | _, _, code, separator = string.find(line, "^(%d%d%d)(.?)") | 27 | _, _, code, separator = string.find(line, "^(%d%d%d)(.?)") |
42 | if not code then return nil, "invalid server reply" end | 28 | if not code then return nil, "invalid server reply" end |
43 | if separator == "-" then -- reply is multiline | 29 | if separator == "-" then -- reply is multiline |
44 | repeat | 30 | repeat |
45 | line, message = try_receiving(sock) | 31 | line, err = sock:receive() |
46 | if message then return nil, message end | 32 | if err then return nil, err end |
47 | _,_, current, separator = string.find(line, "^(%d%d%d)(.)") | 33 | _,_, current, separator = string.find(line, "^(%d%d%d)(.)") |
48 | if not current or not separator then | 34 | if not current or not separator then |
49 | return nil, "invalid server reply" | 35 | return nil, "invalid server reply" |
@@ -58,29 +44,25 @@ end | |||
58 | -- metatable for sock object | 44 | -- metatable for sock object |
59 | local metatable = { __index = {} } | 45 | local metatable = { __index = {} } |
60 | 46 | ||
61 | -- execute the "check" instr | ||
62 | function metatable.__index:check(ok) | 47 | function metatable.__index:check(ok) |
63 | local code, reply = get_reply(self.sock) | 48 | local code, reply = get_reply(self.sock) |
64 | if not code then return nil, reply end | 49 | if not code then return nil, reply end |
65 | if type(ok) ~= "function" then | 50 | if type(ok) ~= "function" then |
66 | if type(ok) ~= "table" then ok = {ok} end | 51 | if type(ok) == "table" then |
67 | for i, v in ipairs(ok) do | 52 | for i, v in ipairs(ok) do |
68 | if string.find(code, v) then return code, reply end | 53 | if string.find(code, v) then return code, reply end |
54 | end | ||
55 | return nil, reply | ||
56 | else | ||
57 | if string.find(code, ok) then return code, reply | ||
58 | else return nil, reply end | ||
69 | end | 59 | end |
70 | return nil, reply | ||
71 | else return ok(code, reply) end | 60 | else return ok(code, reply) end |
72 | end | 61 | end |
73 | 62 | ||
74 | function metatable.__index:cmdchk(cmd, arg, ok) | ||
75 | local code, err = self:command(cmd, arg) | ||
76 | if not code then return nil, err end | ||
77 | return self:check(ok) | ||
78 | end | ||
79 | |||
80 | -- execute the "command" instr | ||
81 | function metatable.__index:command(cmd, arg) | 63 | function metatable.__index:command(cmd, arg) |
82 | if arg then return try_sending(self.sock, cmd .. " " .. arg.. "\r\n") | 64 | if arg then return self.sock:send(cmd .. " " .. arg.. "\r\n") |
83 | return try_sending(self.sock, cmd .. "\r\n") end | 65 | else return self.sock:send(cmd .. "\r\n") end |
84 | end | 66 | end |
85 | 67 | ||
86 | function metatable.__index:sink(snk, pat) | 68 | function metatable.__index:sink(snk, pat) |
@@ -88,6 +70,14 @@ function metatable.__index:sink(snk, pat) | |||
88 | return snk(chunk, err) | 70 | return snk(chunk, err) |
89 | end | 71 | end |
90 | 72 | ||
73 | function metatable.__index:send(data) | ||
74 | return self.sock:send(data) | ||
75 | end | ||
76 | |||
77 | function metatable.__index:receive(pat) | ||
78 | return self.sock:receive(pat) | ||
79 | end | ||
80 | |||
91 | function metatable.__index:source(src, instr) | 81 | function metatable.__index:source(src, instr) |
92 | while true do | 82 | while true do |
93 | local chunk, err = src() | 83 | local chunk, err = src() |