aboutsummaryrefslogtreecommitdiff
path: root/src/tp.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-05-25 05:27:44 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-05-25 05:27:44 +0000
commit888496aa821cd09d925046250ea98b1512293fd5 (patch)
tree217e2b532762a64b58c4fffcb2cba08ba2243462 /src/tp.lua
parent4fc164b8eaa0453050a0a859321c327bb2c4f776 (diff)
downloadluasocket-888496aa821cd09d925046250ea98b1512293fd5.tar.gz
luasocket-888496aa821cd09d925046250ea98b1512293fd5.tar.bz2
luasocket-888496aa821cd09d925046250ea98b1512293fd5.zip
FTP low-level working.
SMTP connection oriented working. ltn12 improved.
Diffstat (limited to 'src/tp.lua')
-rw-r--r--src/tp.lua76
1 files changed, 43 insertions, 33 deletions
diff --git a/src/tp.lua b/src/tp.lua
index 9365255..e9e38a1 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -18,22 +18,19 @@ setfenv(1, socket.tp)
18 18
19TIMEOUT = 60 19TIMEOUT = 60
20 20
21-- gets server reply 21-- gets server reply (works for SMTP and FTP)
22local function get_reply(sock) 22local function get_reply(control)
23 local code, current, separator, _ 23 local code, current, separator, _
24 local line, err = sock:receive() 24 local line, err = control:receive()
25 local reply = line 25 local reply = line
26 if err then return nil, err end 26 if err then return nil, err end
27 _, _, code, separator = string.find(line, "^(%d%d%d)(.?)") 27 _, _, code, separator = string.find(line, "^(%d%d%d)(.?)")
28 if not code then return nil, "invalid server reply" end 28 if not code then return nil, "invalid server reply" end
29 if separator == "-" then -- reply is multiline 29 if separator == "-" then -- reply is multiline
30 repeat 30 repeat
31 line, err = sock:receive() 31 line, err = control:receive()
32 if err then return nil, err end 32 if err then return nil, err end
33 _,_, current, separator = string.find(line, "^(%d%d%d)(.)") 33 _,_, current, separator = string.find(line, "^(%d%d%d)(.?)")
34 if not current or not separator then
35 return nil, "invalid server reply"
36 end
37 reply = reply .. "\n" .. line 34 reply = reply .. "\n" .. line
38 -- reply ends with same code 35 -- reply ends with same code
39 until code == current and separator == " " 36 until code == current and separator == " "
@@ -42,60 +39,73 @@ local function get_reply(sock)
42end 39end
43 40
44-- metatable for sock object 41-- metatable for sock object
45local metatable = { __index = {} } 42local metat = { __index = {} }
46 43
47function metatable.__index:check(ok) 44function metat.__index:check(ok)
48 local code, reply = get_reply(self.sock) 45 local code, reply = get_reply(self.control)
49 if not code then return nil, reply end 46 if not code then return nil, reply end
50 if type(ok) ~= "function" then 47 if type(ok) ~= "function" then
51 if type(ok) == "table" then 48 if type(ok) == "table" then
52 for i, v in ipairs(ok) do 49 for i, v in ipairs(ok) do
53 if string.find(code, v) then return code, reply end 50 if string.find(code, v) then return tonumber(code), reply end
54 end 51 end
55 return nil, reply 52 return nil, reply
56 else 53 else
57 if string.find(code, ok) then return code, reply 54 if string.find(code, ok) then return tonumber(code), reply
58 else return nil, reply end 55 else return nil, reply end
59 end 56 end
60 else return ok(code, reply) end 57 else return ok(tonumber(code), reply) end
61end 58end
62 59
63function metatable.__index:command(cmd, arg) 60function metat.__index:command(cmd, arg)
64 if arg then return self.sock:send(cmd .. " " .. arg.. "\r\n") 61 if arg then return self.control:send(cmd .. " " .. arg.. "\r\n")
65 else return self.sock:send(cmd .. "\r\n") end 62 else return self.control:send(cmd .. "\r\n") end
66end 63end
67 64
68function metatable.__index:sink(snk, pat) 65function metat.__index:sink(snk, pat)
69 local chunk, err = sock:receive(pat) 66 local chunk, err = control:receive(pat)
70 return snk(chunk, err) 67 return snk(chunk, err)
71end 68end
72 69
73function metatable.__index:send(data) 70function metat.__index:send(data)
74 return self.sock:send(data) 71 return self.control:send(data)
72end
73
74function metat.__index:receive(pat)
75 return self.control:receive(pat)
76end
77
78function metat.__index:getfd()
79 return self.control:getfd()
80end
81
82function metat.__index:dirty()
83 return self.control:dirty()
75end 84end
76 85
77function metatable.__index:receive(pat) 86function metat.__index:getcontrol()
78 return self.sock:receive(pat) 87 return self.control
79end 88end
80 89
81function metatable.__index:source(src, instr) 90function metat.__index:source(src, instr)
82 while true do 91 while true do
83 local chunk, err = src() 92 local chunk, err = src()
84 if not chunk then return not err, err end 93 if not chunk then return not err, err end
85 local ret, err = self.sock:send(chunk) 94 local ret, err = self.control:send(chunk)
86 if not ret then return nil, err end 95 if not ret then return nil, err end
87 end 96 end
88end 97end
89 98
90-- closes the underlying sock 99-- closes the underlying control
91function metatable.__index:close() 100function metat.__index:close()
92 self.sock:close() 101 self.control:close()
102 return 1
93end 103end
94 104
95-- connect with server and return sock object 105-- connect with server and return control object
96function connect(host, port) 106function connect(host, port)
97 local sock, err = socket.connect(host, port) 107 local control, err = socket.connect(host, port)
98 if not sock then return nil, err end 108 if not control then return nil, err end
99 sock:settimeout(TIMEOUT) 109 control:settimeout(TIMEOUT)
100 return setmetatable({sock = sock}, metatable) 110 return setmetatable({control = control}, metat)
101end 111end