aboutsummaryrefslogtreecommitdiff
path: root/src/ftp.lua
diff options
context:
space:
mode:
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