aboutsummaryrefslogtreecommitdiff
path: root/vendor/luasocket/src/tp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/luasocket/src/tp.lua')
-rw-r--r--vendor/luasocket/src/tp.lua134
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-----------------------------------------------------------------------------
10local base = _G
11local string = require("string")
12local socket = require("socket")
13local ltn12 = require("ltn12")
14
15socket.tp = {}
16local _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)
27local 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
44end
45
46-- metatable for sock object
47local metat = { __index = {} }
48
49function metat.__index:getpeername()
50 return self.c:getpeername()
51end
52
53function metat.__index:getsockname()
54 return self.c:getpeername()
55end
56
57function 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
73end
74
75function 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
82end
83
84function metat.__index:sink(snk, pat)
85 local chunk, err = self.c:receive(pat)
86 return snk(chunk, err)
87end
88
89function metat.__index:send(data)
90 return self.c:send(data)
91end
92
93function metat.__index:receive(pat)
94 return self.c:receive(pat)
95end
96
97function metat.__index:getfd()
98 return self.c:getfd()
99end
100
101function metat.__index:dirty()
102 return self.c:dirty()
103end
104
105function metat.__index:getcontrol()
106 return self.c
107end
108
109function 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
113end
114
115-- closes the underlying c
116function metat.__index:close()
117 self.c:close()
118 return 1
119end
120
121-- connect with server and return c object
122function _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)
132end
133
134return _M