diff options
Diffstat (limited to 'src/ftp.lua')
-rw-r--r-- | src/ftp.lua | 73 |
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 | ----------------------------------------------------------------------------- |
12 | local socket = require("socket") | 12 | local socket = require("socket") |
13 | local ltn12 = require("ltn12") | 13 | local ltn12 = require("ltn12") |
@@ -17,10 +17,7 @@ local tp = require("tp") | |||
17 | ----------------------------------------------------------------------------- | 17 | ----------------------------------------------------------------------------- |
18 | -- Setup namespace | 18 | -- Setup namespace |
19 | ----------------------------------------------------------------------------- | 19 | ----------------------------------------------------------------------------- |
20 | local ftp = {} | 20 | _LOADED["ftp"] = getfenv(1) |
21 | -- make all module globals fall into namespace | ||
22 | setmetatable(ftp, { __index = _G }) | ||
23 | setfenv(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. |
34 | USER = "ftp" | 31 | USER = "ftp" |
35 | EMAIL = "anonymous@anonymous.org" | 32 | PASSWORD = "anonymous@anonymous.org" |
36 | -- block size used in transfers | ||
37 | BLOCKSIZE = 2048 | ||
38 | 33 | ||
39 | ----------------------------------------------------------------------------- | 34 | ----------------------------------------------------------------------------- |
40 | -- Low level FTP API | 35 | -- Low level FTP API |
@@ -42,7 +37,7 @@ BLOCKSIZE = 2048 | |||
42 | local metat = { __index = {} } | 37 | local metat = { __index = {} } |
43 | 38 | ||
44 | function open(server, port) | 39 | function 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) |
47 | end | 42 | end |
48 | 43 | ||
@@ -51,14 +46,17 @@ local function port(portt) | |||
51 | end | 46 | end |
52 | 47 | ||
53 | local function pasv(pasvt) | 48 | local 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 | ||
55 | end | 53 | end |
56 | 54 | ||
57 | function metat.__index:login(user, password) | 55 | function 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 | ----------------------------------------------------------------------------- |
184 | local function tput(putt) | 184 | local 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() |
193 | end | 193 | end |
194 | 194 | ||
195 | local default = { | 195 | local default = { |
@@ -198,15 +198,16 @@ local default = { | |||
198 | } | 198 | } |
199 | 199 | ||
200 | local function parse(u) | 200 | local 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 |
210 | end | 211 | end |
211 | 212 | ||
212 | local function sput(u, body) | 213 | local function sput(u, body) |
@@ -221,17 +222,17 @@ put = socket.protect(function(putt, body) | |||
221 | end) | 222 | end) |
222 | 223 | ||
223 | local function tget(gett) | 224 | local 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() |
232 | end | 233 | end |
233 | 234 | ||
234 | local function sget(u, body) | 235 | local 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) | |||
240 | end | 241 | end |
241 | 242 | ||
242 | get = socket.protect(function(gett) | 243 | get = 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 |
245 | end) | 246 | end) |
246 | 247 | ||