aboutsummaryrefslogtreecommitdiff
path: root/src/ftp.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-06-15 06:24:00 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-06-15 06:24:00 +0000
commit58096449c6044b7aade5cd41cfd71c6bec1d273d (patch)
tree1814ffebe89c4c2556d84f97f66db37a7e8b4554 /src/ftp.lua
parent9ed7f955e5fc69af9bf1794fa2c8cd227981ba24 (diff)
downloadluasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.tar.gz
luasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.tar.bz2
luasocket-58096449c6044b7aade5cd41cfd71c6bec1d273d.zip
Manual is almost done. HTTP is missing.
Implemented new distribution scheme. Select is now purely C. HTTP reimplemented seems faster dunno why. LTN12 functions that coroutines fail gracefully.
Diffstat (limited to 'src/ftp.lua')
-rw-r--r--src/ftp.lua73
1 files changed, 37 insertions, 36 deletions
diff --git a/src/ftp.lua b/src/ftp.lua
index 79772f8..c130d1a 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -7,7 +7,7 @@
7----------------------------------------------------------------------------- 7-----------------------------------------------------------------------------
8 8
9----------------------------------------------------------------------------- 9-----------------------------------------------------------------------------
10-- Load other required modules 10-- Load required modules
11----------------------------------------------------------------------------- 11-----------------------------------------------------------------------------
12local socket = require("socket") 12local socket = require("socket")
13local ltn12 = require("ltn12") 13local ltn12 = require("ltn12")
@@ -17,10 +17,7 @@ local tp = require("tp")
17----------------------------------------------------------------------------- 17-----------------------------------------------------------------------------
18-- Setup namespace 18-- Setup namespace
19----------------------------------------------------------------------------- 19-----------------------------------------------------------------------------
20local ftp = {} 20_LOADED["ftp"] = getfenv(1)
21-- make all module globals fall into namespace
22setmetatable(ftp, { __index = _G })
23setfenv(1, ftp)
24 21
25----------------------------------------------------------------------------- 22-----------------------------------------------------------------------------
26-- Program constants 23-- Program constants
@@ -32,9 +29,7 @@ PORT = 21
32-- this is the default anonymous password. used when no password is 29-- this is the default anonymous password. used when no password is
33-- provided in url. should be changed to your e-mail. 30-- provided in url. should be changed to your e-mail.
34USER = "ftp" 31USER = "ftp"
35EMAIL = "anonymous@anonymous.org" 32PASSWORD = "anonymous@anonymous.org"
36-- block size used in transfers
37BLOCKSIZE = 2048
38 33
39----------------------------------------------------------------------------- 34-----------------------------------------------------------------------------
40-- Low level FTP API 35-- Low level FTP API
@@ -42,7 +37,7 @@ BLOCKSIZE = 2048
42local metat = { __index = {} } 37local metat = { __index = {} }
43 38
44function open(server, port) 39function open(server, port)
45 local tp = socket.try(socket.tp.connect(server, port or PORT)) 40 local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
46 return setmetatable({tp = tp}, metat) 41 return setmetatable({tp = tp}, metat)
47end 42end
48 43
@@ -51,14 +46,17 @@ local function port(portt)
51end 46end
52 47
53local function pasv(pasvt) 48local function pasv(pasvt)
54 return socket.connect(pasvt.ip, pasvt.port) 49 local data = socket.try(socket.tcp())
50 socket.try(data:settimeout(TIMEOUT))
51 socket.try(data:connect(pasvt.ip, pasvt.port))
52 return data
55end 53end
56 54
57function metat.__index:login(user, password) 55function metat.__index:login(user, password)
58 socket.try(self.tp:command("user", user or USER)) 56 socket.try(self.tp:command("user", user or USER))
59 local code, reply = socket.try(self.tp:check{"2..", 331}) 57 local code, reply = socket.try(self.tp:check{"2..", 331})
60 if code == 331 then 58 if code == 331 then
61 socket.try(self.tp:command("pass", password or EMAIL)) 59 socket.try(self.tp:command("pass", password or PASSWORD))
62 socket.try(self.tp:check("2..")) 60 socket.try(self.tp:check("2.."))
63 end 61 end
64 return 1 62 return 1
@@ -104,6 +102,7 @@ function metat.__index:send(sendt)
104 socket.try(self.pasvt or self.portt, "need port or pasv first") 102 socket.try(self.pasvt or self.portt, "need port or pasv first")
105 if self.pasvt then data = socket.try(pasv(self.pasvt)) end 103 if self.pasvt then data = socket.try(pasv(self.pasvt)) end
106 local argument = sendt.argument or string.gsub(sendt.path, "^/", "") 104 local argument = sendt.argument or string.gsub(sendt.path, "^/", "")
105 if argument == "" then argument = nil end
107 local command = sendt.command or "stor" 106 local command = sendt.command or "stor"
108 socket.try(self.tp:command(command, argument)) 107 socket.try(self.tp:command(command, argument))
109 local code, reply = socket.try(self.tp:check{"2..", "1.."}) 108 local code, reply = socket.try(self.tp:check{"2..", "1.."})
@@ -133,6 +132,7 @@ function metat.__index:receive(recvt)
133 socket.try(self.pasvt or self.portt, "need port or pasv first") 132 socket.try(self.pasvt or self.portt, "need port or pasv first")
134 if self.pasvt then data = socket.try(pasv(self.pasvt)) end 133 if self.pasvt then data = socket.try(pasv(self.pasvt)) end
135 local argument = recvt.argument or string.gsub(recvt.path, "^/", "") 134 local argument = recvt.argument or string.gsub(recvt.path, "^/", "")
135 if argument == "" then argument = nil end
136 local command = recvt.command or "retr" 136 local command = recvt.command or "retr"
137 socket.try(self.tp:command(command, argument)) 137 socket.try(self.tp:command(command, argument))
138 local code = socket.try(self.tp:check{"1..", "2.."}) 138 local code = socket.try(self.tp:check{"1..", "2.."})
@@ -182,14 +182,14 @@ end
182-- High level FTP API 182-- High level FTP API
183----------------------------------------------------------------------------- 183-----------------------------------------------------------------------------
184local function tput(putt) 184local function tput(putt)
185 local ftp = socket.ftp.open(putt.host, putt.port) 185 local con = ftp.open(putt.host, putt.port)
186 ftp:greet() 186 con:greet()
187 ftp:login(putt.user, putt.password) 187 con:login(putt.user, putt.password)
188 if putt.type then ftp:type(putt.type) end 188 if putt.type then con:type(putt.type) end
189 ftp:pasv() 189 con:pasv()
190 ftp:send(putt) 190 con:send(putt)
191 ftp:quit() 191 con:quit()
192 return ftp:close() 192 return con:close()
193end 193end
194 194
195local default = { 195local default = {
@@ -198,15 +198,16 @@ local default = {
198} 198}
199 199
200local function parse(u) 200local function parse(u)
201 local putt = socket.try(url.parse(u, default)) 201 local t = socket.try(url.parse(u, default))
202 socket.try(putt.scheme == "ftp", "invalid scheme '" .. putt.scheme .. "'") 202 socket.try(t.scheme == "ftp", "invalid scheme '" .. t.scheme .. "'")
203 socket.try(putt.host, "invalid host") 203 socket.try(t.host, "invalid host")
204 local pat = "^type=(.)$" 204 local pat = "^type=(.)$"
205 if putt.params then 205 if t.params then
206 putt.type = socket.skip(2, string.find(putt.params, pat)) 206 t.type = socket.skip(2, string.find(t.params, pat))
207 socket.try(putt.type == "a" or putt.type == "i") 207 socket.try(t.type == "a" or t.type == "i",
208 "invalid type '" .. t.type .. "'")
208 end 209 end
209 return putt 210 return t
210end 211end
211 212
212local function sput(u, body) 213local function sput(u, body)
@@ -221,17 +222,17 @@ put = socket.protect(function(putt, body)
221end) 222end)
222 223
223local function tget(gett) 224local function tget(gett)
224 local ftp = socket.ftp.open(gett.host, gett.port) 225 local con = ftp.open(gett.host, gett.port)
225 ftp:greet() 226 con:greet()
226 ftp:login(gett.user, gett.password) 227 con:login(gett.user, gett.password)
227 if gett.type then ftp:type(gett.type) end 228 if gett.type then con:type(gett.type) end
228 ftp:pasv() 229 con:pasv()
229 ftp:receive(gett) 230 con:receive(gett)
230 ftp:quit() 231 con:quit()
231 return ftp:close() 232 return con:close()
232end 233end
233 234
234local function sget(u, body) 235local function sget(u)
235 local gett = parse(u) 236 local gett = parse(u)
236 local t = {} 237 local t = {}
237 gett.sink = ltn12.sink.table(t) 238 gett.sink = ltn12.sink.table(t)
@@ -240,7 +241,7 @@ local function sget(u, body)
240end 241end
241 242
242get = socket.protect(function(gett) 243get = socket.protect(function(gett)
243 if type(gett) == "string" then return sget(gett, body) 244 if type(gett) == "string" then return sget(gett)
244 else return tget(gett) end 245 else return tget(gett) end
245end) 246end)
246 247