diff options
Diffstat (limited to 'vendor/luasocket/src/tp.lua')
-rw-r--r-- | vendor/luasocket/src/tp.lua | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/vendor/luasocket/src/tp.lua b/vendor/luasocket/src/tp.lua new file mode 100644 index 00000000..b8ebc56d --- /dev/null +++ b/vendor/luasocket/src/tp.lua | |||
@@ -0,0 +1,134 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- Unified SMTP/FTP subsystem | ||
3 | -- LuaSocket toolkit. | ||
4 | -- Author: Diego Nehab | ||
5 | ----------------------------------------------------------------------------- | ||
6 | |||
7 | ----------------------------------------------------------------------------- | ||
8 | -- Declare module and import dependencies | ||
9 | ----------------------------------------------------------------------------- | ||
10 | local base = _G | ||
11 | local string = require("string") | ||
12 | local socket = require("socket") | ||
13 | local ltn12 = require("ltn12") | ||
14 | |||
15 | socket.tp = {} | ||
16 | local _M = socket.tp | ||
17 | |||
18 | ----------------------------------------------------------------------------- | ||
19 | -- Program constants | ||
20 | ----------------------------------------------------------------------------- | ||
21 | _M.TIMEOUT = 60 | ||
22 | |||
23 | ----------------------------------------------------------------------------- | ||
24 | -- Implementation | ||
25 | ----------------------------------------------------------------------------- | ||
26 | -- gets server reply (works for SMTP and FTP) | ||
27 | local function get_reply(c) | ||
28 | local code, current, sep | ||
29 | local line, err = c:receive() | ||
30 | local reply = line | ||
31 | if err then return nil, err end | ||
32 | code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) | ||
33 | if not code then return nil, "invalid server reply" end | ||
34 | if sep == "-" then -- reply is multiline | ||
35 | repeat | ||
36 | line, err = c:receive() | ||
37 | if err then return nil, err end | ||
38 | current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) | ||
39 | reply = reply .. "\n" .. line | ||
40 | -- reply ends with same code | ||
41 | until code == current and sep == " " | ||
42 | end | ||
43 | return code, reply | ||
44 | end | ||
45 | |||
46 | -- metatable for sock object | ||
47 | local metat = { __index = {} } | ||
48 | |||
49 | function metat.__index:getpeername() | ||
50 | return self.c:getpeername() | ||
51 | end | ||
52 | |||
53 | function metat.__index:getsockname() | ||
54 | return self.c:getpeername() | ||
55 | end | ||
56 | |||
57 | function metat.__index:check(ok) | ||
58 | local code, reply = get_reply(self.c) | ||
59 | if not code then return nil, reply end | ||
60 | if base.type(ok) ~= "function" then | ||
61 | if base.type(ok) == "table" then | ||
62 | for i, v in base.ipairs(ok) do | ||
63 | if string.find(code, v) then | ||
64 | return base.tonumber(code), reply | ||
65 | end | ||
66 | end | ||
67 | return nil, reply | ||
68 | else | ||
69 | if string.find(code, ok) then return base.tonumber(code), reply | ||
70 | else return nil, reply end | ||
71 | end | ||
72 | else return ok(base.tonumber(code), reply) end | ||
73 | end | ||
74 | |||
75 | function metat.__index:command(cmd, arg) | ||
76 | cmd = string.upper(cmd) | ||
77 | if arg then | ||
78 | return self.c:send(cmd .. " " .. arg.. "\r\n") | ||
79 | else | ||
80 | return self.c:send(cmd .. "\r\n") | ||
81 | end | ||
82 | end | ||
83 | |||
84 | function metat.__index:sink(snk, pat) | ||
85 | local chunk, err = self.c:receive(pat) | ||
86 | return snk(chunk, err) | ||
87 | end | ||
88 | |||
89 | function metat.__index:send(data) | ||
90 | return self.c:send(data) | ||
91 | end | ||
92 | |||
93 | function metat.__index:receive(pat) | ||
94 | return self.c:receive(pat) | ||
95 | end | ||
96 | |||
97 | function metat.__index:getfd() | ||
98 | return self.c:getfd() | ||
99 | end | ||
100 | |||
101 | function metat.__index:dirty() | ||
102 | return self.c:dirty() | ||
103 | end | ||
104 | |||
105 | function metat.__index:getcontrol() | ||
106 | return self.c | ||
107 | end | ||
108 | |||
109 | function metat.__index:source(source, step) | ||
110 | local sink = socket.sink("keep-open", self.c) | ||
111 | local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step) | ||
112 | return ret, err | ||
113 | end | ||
114 | |||
115 | -- closes the underlying c | ||
116 | function metat.__index:close() | ||
117 | self.c:close() | ||
118 | return 1 | ||
119 | end | ||
120 | |||
121 | -- connect with server and return c object | ||
122 | function _M.connect(host, port, timeout, create) | ||
123 | local c, e = (create or socket.tcp)() | ||
124 | if not c then return nil, e end | ||
125 | c:settimeout(timeout or _M.TIMEOUT) | ||
126 | local r, e = c:connect(host, port) | ||
127 | if not r then | ||
128 | c:close() | ||
129 | return nil, e | ||
130 | end | ||
131 | return base.setmetatable({c = c}, metat) | ||
132 | end | ||
133 | |||
134 | return _M | ||