diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-05-25 05:27:44 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-05-25 05:27:44 +0000 |
| commit | 888496aa821cd09d925046250ea98b1512293fd5 (patch) | |
| tree | 217e2b532762a64b58c4fffcb2cba08ba2243462 /src/tp.lua | |
| parent | 4fc164b8eaa0453050a0a859321c327bb2c4f776 (diff) | |
| download | luasocket-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.lua | 76 |
1 files changed, 43 insertions, 33 deletions
| @@ -18,22 +18,19 @@ setfenv(1, socket.tp) | |||
| 18 | 18 | ||
| 19 | TIMEOUT = 60 | 19 | TIMEOUT = 60 |
| 20 | 20 | ||
| 21 | -- gets server reply | 21 | -- gets server reply (works for SMTP and FTP) |
| 22 | local function get_reply(sock) | 22 | local 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) | |||
| 42 | end | 39 | end |
| 43 | 40 | ||
| 44 | -- metatable for sock object | 41 | -- metatable for sock object |
| 45 | local metatable = { __index = {} } | 42 | local metat = { __index = {} } |
| 46 | 43 | ||
| 47 | function metatable.__index:check(ok) | 44 | function 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 |
| 61 | end | 58 | end |
| 62 | 59 | ||
| 63 | function metatable.__index:command(cmd, arg) | 60 | function 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 |
| 66 | end | 63 | end |
| 67 | 64 | ||
| 68 | function metatable.__index:sink(snk, pat) | 65 | function 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) |
| 71 | end | 68 | end |
| 72 | 69 | ||
| 73 | function metatable.__index:send(data) | 70 | function metat.__index:send(data) |
| 74 | return self.sock:send(data) | 71 | return self.control:send(data) |
| 72 | end | ||
| 73 | |||
| 74 | function metat.__index:receive(pat) | ||
| 75 | return self.control:receive(pat) | ||
| 76 | end | ||
| 77 | |||
| 78 | function metat.__index:getfd() | ||
| 79 | return self.control:getfd() | ||
| 80 | end | ||
| 81 | |||
| 82 | function metat.__index:dirty() | ||
| 83 | return self.control:dirty() | ||
| 75 | end | 84 | end |
| 76 | 85 | ||
| 77 | function metatable.__index:receive(pat) | 86 | function metat.__index:getcontrol() |
| 78 | return self.sock:receive(pat) | 87 | return self.control |
| 79 | end | 88 | end |
| 80 | 89 | ||
| 81 | function metatable.__index:source(src, instr) | 90 | function 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 |
| 88 | end | 97 | end |
| 89 | 98 | ||
| 90 | -- closes the underlying sock | 99 | -- closes the underlying control |
| 91 | function metatable.__index:close() | 100 | function metat.__index:close() |
| 92 | self.sock:close() | 101 | self.control:close() |
| 102 | return 1 | ||
| 93 | end | 103 | end |
| 94 | 104 | ||
| 95 | -- connect with server and return sock object | 105 | -- connect with server and return control object |
| 96 | function connect(host, port) | 106 | function 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) |
| 101 | end | 111 | end |
