1
2
3
4local setmetatable , next , type , tonumber = setmetatable , next , type , tonumber
5local find , upper = string . find , string . upper
6
7local socket = socket or require ( " socket " )
8local ltn12 = ltn12 or require ( " ltn12 " )
9
10local skipsocket = socket . skip
11local sinksocket = socket . sink
12local tcpsocket = socket . tcp
13
14local ltn12pump = ltn12 . pump
15local pumpall = ltn12pump . all
16local pumpstep = ltn12pump . step
17
18local tp = {
19 TIMEOUT = 60 ,
20}
21
22socket . tp = tp
23
24local function get_reply ( c )
25 local line , err = c : receive ( )
26 local reply = line
27 if err then return
28 nil , err
29 end
30 local code , sep = skipsocket ( 2 , find ( line , " ^(%d%d%d)(.?) " ) )
31 if not code then
32 return nil , " invalid server reply "
33 end
34 if sep = = " - " then
35 local current
36 repeat
37 line , err = c : receive ( )
38 if err then
39 return nil , err
40 end
41 current , sep = skipsocket ( 2 , find ( line , " ^(%d%d%d)(.?) " ) )
42 reply = reply . . " \n " . . line
43 until code = = current and sep = = " "
44 end
45 return code , reply
46end
47
48local methods = { }
49local mt = { __index = methods }
50
51function methods . getpeername ( self )
52 return self . c : getpeername ( )
53end
54
55function methods . getsockname ( self )
56 return self . c : getpeername ( )
57end
58
59function methods . check ( self , ok )
60 local code , reply = get_reply ( self . c )
61 if not code then
62 return nil , reply
63 end
64 local c = tonumber ( code )
65 local t = type ( ok )
66 if t = = " function " then
67 return ok ( c , reply )
68 elseif t = = " table " then
69 for i = 1 , # ok do
70 if find ( code , ok [ i ] ) then
71 return c , reply
72 end
73 end
74 return nil , reply
75 elseif find ( code , ok ) then
76 return c , reply
77 else
78 return nil , reply
79 end
80end
81
82function methods . command ( self , cmd , arg )
83 cmd = upper ( cmd )
84 if arg then
85 cmd = cmd . . " " . . arg . . " \r\n "
86 else
87 cmd = cmd . . " \r\n "
88 end
89 return self . c : send ( cmd )
90end
91
92function methods . sink ( self , snk , pat )
93 local chunk , err = self . c : receive ( pat )
94 return snk ( chunk , err )
95end
96
97function methods . send ( self , data )
98 return self . c : send ( data )
99end
100
101function methods . receive ( self , pat )
102 return self . c : receive ( pat )
103end
104
105function methods . getfd ( self )
106 return self . c : getfd ( )
107end
108
109function methods . dirty ( self )
110 return self . c : dirty ( )
111end
112
113function methods . getcontrol ( self )
114 return self . c
115end
116
117function methods . source ( self , source , step )
118 local sink = sinksocket ( " keep-open " , self . c )
119 local ret , err = pumpall ( source , sink , step or pumpstep )
120 return ret , err
121end
122
123function methods . close ( self )
124 self . c : close ( )
125 return 1
126end
127
128function tp . connect ( host , port , timeout , create )
129 local c , e = ( create or tcpsocket ) ( )
130 if not c then
131 return nil , e
132 end
133 c : settimeout ( timeout or tp . TIMEOUT )
134 local r , e = c : connect ( host , port )
135 if not r then
136 c : close ( )
137 return nil , e
138 end
139 return setmetatable ( { c = c } , mt )
140end
141
142package . loaded [ " socket.tp " ] = tp
143
144return tp
145 |