diff src/tp.lua @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tp.lua	Tue Aug 26 18:40:01 2008 -0700
@@ -0,0 +1,123 @@
+-----------------------------------------------------------------------------
+-- Unified SMTP/FTP subsystem
+-- LuaSocket toolkit.
+-- Author: Diego Nehab
+-- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+-- Declare module and import dependencies
+-----------------------------------------------------------------------------
+local base = _G
+local string = require("string")
+local socket = require("socket")
+local ltn12 = require("ltn12")
+module("socket.tp")
+
+-----------------------------------------------------------------------------
+-- Program constants
+-----------------------------------------------------------------------------
+TIMEOUT = 60
+
+-----------------------------------------------------------------------------
+-- Implementation
+-----------------------------------------------------------------------------
+-- gets server reply (works for SMTP and FTP)
+local function get_reply(c)
+    local code, current, sep
+    local line, err = c:receive()
+    local reply = line
+    if err then return nil, err end
+    code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
+    if not code then return nil, "invalid server reply" end
+    if sep == "-" then -- reply is multiline
+        repeat
+            line, err = c:receive()
+            if err then return nil, err end
+            current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
+            reply = reply .. "\n" .. line
+        -- reply ends with same code
+        until code == current and sep == " "
+    end
+    return code, reply
+end
+
+-- metatable for sock object
+local metat = { __index = {} }
+
+function metat.__index:check(ok)
+    local code, reply = get_reply(self.c)
+    if not code then return nil, reply end
+    if base.type(ok) ~= "function" then
+        if base.type(ok) == "table" then
+            for i, v in base.ipairs(ok) do
+                if string.find(code, v) then
+                    return base.tonumber(code), reply
+                end
+            end
+            return nil, reply
+        else
+            if string.find(code, ok) then return base.tonumber(code), reply
+            else return nil, reply end
+        end
+    else return ok(base.tonumber(code), reply) end
+end
+
+function metat.__index:command(cmd, arg)
+    if arg then
+        return self.c:send(cmd .. " " .. arg.. "\r\n")
+    else
+        return self.c:send(cmd .. "\r\n")
+    end
+end
+
+function metat.__index:sink(snk, pat)
+    local chunk, err = c:receive(pat)
+    return snk(chunk, err)
+end
+
+function metat.__index:send(data)
+    return self.c:send(data)
+end
+
+function metat.__index:receive(pat)
+    return self.c:receive(pat)
+end
+
+function metat.__index:getfd()
+    return self.c:getfd()
+end
+
+function metat.__index:dirty()
+    return self.c:dirty()
+end
+
+function metat.__index:getcontrol()
+    return self.c
+end
+
+function metat.__index:source(source, step)
+    local sink = socket.sink("keep-open", self.c)
+    local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
+    return ret, err
+end
+
+-- closes the underlying c
+function metat.__index:close()
+    self.c:close()
+	return 1
+end
+
+-- connect with server and return c object
+function connect(host, port, timeout, create)
+    local c, e = (create or socket.tcp)()
+    if not c then return nil, e end
+    c:settimeout(timeout or TIMEOUT)
+    local r, e = c:connect(host, port)
+    if not r then
+        c:close()
+        return nil, e
+    end
+    return base.setmetatable({c = c}, metat)
+end
+