diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-06-15 06:24:00 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-06-15 06:24:00 +0000 |
commit | 58096449c6044b7aade5cd41cfd71c6bec1d273d (patch) | |
tree | 1814ffebe89c4c2556d84f97f66db37a7e8b4554 /src/ftp.lua | |
parent | 9ed7f955e5fc69af9bf1794fa2c8cd227981ba24 (diff) | |
download | luasocket-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.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 | ||