aboutsummaryrefslogtreecommitdiff
path: root/src/ftp.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-05-28 06:16:43 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-05-28 06:16:43 +0000
commit694edcc3c1ac3041ff8cdd753a2f7894e8783e6c (patch)
treef8797b4c7671fbf9042fc011277d69d4c3549045 /src/ftp.lua
parentbf738a03368b8de9c574d9631f131c5a520acf7b (diff)
downloadluasocket-694edcc3c1ac3041ff8cdd753a2f7894e8783e6c.tar.gz
luasocket-694edcc3c1ac3041ff8cdd753a2f7894e8783e6c.tar.bz2
luasocket-694edcc3c1ac3041ff8cdd753a2f7894e8783e6c.zip
Committing with require.
Diffstat (limited to 'src/ftp.lua')
-rw-r--r--src/ftp.lua89
1 files changed, 76 insertions, 13 deletions
diff --git a/src/ftp.lua b/src/ftp.lua
index 306b77f..efb872a 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -10,6 +10,11 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
10-- get LuaSocket namespace 10-- get LuaSocket namespace
11local socket = _G[LUASOCKET_LIBNAME] 11local socket = _G[LUASOCKET_LIBNAME]
12if not socket then error('module requires LuaSocket') end 12if not socket then error('module requires LuaSocket') end
13
14-- require other modules
15require("ltn12")
16require("url")
17
13-- create namespace inside LuaSocket namespace 18-- create namespace inside LuaSocket namespace
14socket.ftp = socket.ftp or {} 19socket.ftp = socket.ftp or {}
15-- make all module globals fall into namespace 20-- make all module globals fall into namespace
@@ -25,6 +30,7 @@ TIMEOUT = 60
25PORT = 21 30PORT = 21
26-- this is the default anonymous password. used when no password is 31-- this is the default anonymous password. used when no password is
27-- provided in url. should be changed to your e-mail. 32-- provided in url. should be changed to your e-mail.
33USER = "ftp"
28EMAIL = "anonymous@anonymous.org" 34EMAIL = "anonymous@anonymous.org"
29-- block size used in transfers 35-- block size used in transfers
30BLOCKSIZE = 2048 36BLOCKSIZE = 2048
@@ -48,21 +54,20 @@ local function pasv(pasvt)
48end 54end
49 55
50function metat.__index:login(user, password) 56function metat.__index:login(user, password)
51 socket.try(self.tp:command("USER", user)) 57 socket.try(self.tp:command("user", user or USER))
52 local code, reply = socket.try(self.tp:check{"2..", 331}) 58 local code, reply = socket.try(self.tp:check{"2..", 331})
53 if code == 331 then 59 if code == 331 then
54 socket.try(password, reply) 60 socket.try(self.tp:command("pass", password or EMAIL))
55 socket.try(self.tp:command("PASS", password))
56 socket.try(self.tp:check("2..")) 61 socket.try(self.tp:check("2.."))
57 end 62 end
58 return 1 63 return 1
59end 64end
60 65
61function metat.__index:pasv() 66function metat.__index:pasv()
62 socket.try(self.tp:command("PASV")) 67 socket.try(self.tp:command("pasv"))
63 local code, reply = socket.try(self.tp:check("2..")) 68 local code, reply = socket.try(self.tp:check("2.."))
64 local _, _, a, b, c, d, p1, p2 = 69 local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
65 string.find(reply, "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)") 70 local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
66 socket.try(a and b and c and d and p1 and p2, reply) 71 socket.try(a and b and c and d and p1 and p2, reply)
67 self.pasvt = { 72 self.pasvt = {
68 ip = string.format("%d.%d.%d.%d", a, b, c, d), 73 ip = string.format("%d.%d.%d.%d", a, b, c, d),
@@ -97,7 +102,7 @@ function metat.__index:send(sendt)
97 local data 102 local data
98 socket.try(self.pasvt or self.portt, "need port or pasv first") 103 socket.try(self.pasvt or self.portt, "need port or pasv first")
99 if self.pasvt then data = socket.try(pasv(self.pasvt)) end 104 if self.pasvt then data = socket.try(pasv(self.pasvt)) end
100 socket.try(self.tp:command(sendt.command, sendt.argument)) 105 socket.try(self.tp:command(sendt.command or "stor", sendt.argument))
101 local code, reply = socket.try(self.tp:check{"2..", "1.."}) 106 local code, reply = socket.try(self.tp:check{"2..", "1.."})
102 if self.portt then data = socket.try(port(self.portt)) end 107 if self.portt then data = socket.try(port(self.portt)) end
103 local step = sendt.step or ltn12.pump.step 108 local step = sendt.step or ltn12.pump.step
@@ -124,7 +129,7 @@ function metat.__index:receive(recvt)
124 local data 129 local data
125 socket.try(self.pasvt or self.portt, "need port or pasv first") 130 socket.try(self.pasvt or self.portt, "need port or pasv first")
126 if self.pasvt then data = socket.try(pasv(self.pasvt)) end 131 if self.pasvt then data = socket.try(pasv(self.pasvt)) end
127 socket.try(self.tp:command(recvt.command, recvt.argument)) 132 socket.try(self.tp:command(recvt.command or "retr", recvt.argument))
128 local code = socket.try(self.tp:check{"1..", "2.."}) 133 local code = socket.try(self.tp:check{"1..", "2.."})
129 if self.portt then data = socket.try(port(self.portt)) end 134 if self.portt then data = socket.try(port(self.portt)) end
130 local source = socket.source("until-closed", data) 135 local source = socket.source("until-closed", data)
@@ -140,13 +145,13 @@ function metat.__index:receive(recvt)
140end 145end
141 146
142function metat.__index:cwd(dir) 147function metat.__index:cwd(dir)
143 socket.try(self.tp:command("CWD", dir)) 148 socket.try(self.tp:command("cwd", dir))
144 socket.try(self.tp:check(250)) 149 socket.try(self.tp:check(250))
145 return 1 150 return 1
146end 151end
147 152
148function metat.__index:type(type) 153function metat.__index:type(type)
149 socket.try(self.tp:command("TYPE", type)) 154 socket.try(self.tp:command("type", type))
150 socket.try(self.tp:check(200)) 155 socket.try(self.tp:check(200))
151 return 1 156 return 1
152end 157end
@@ -158,7 +163,7 @@ function metat.__index:greet()
158end 163end
159 164
160function metat.__index:quit() 165function metat.__index:quit()
161 socket.try(self.tp:command("QUIT")) 166 socket.try(self.tp:command("quit"))
162 socket.try(self.tp:check("2..")) 167 socket.try(self.tp:check("2.."))
163 return 1 168 return 1
164end 169end
@@ -171,11 +176,69 @@ end
171----------------------------------------------------------------------------- 176-----------------------------------------------------------------------------
172-- High level FTP API 177-- High level FTP API
173----------------------------------------------------------------------------- 178-----------------------------------------------------------------------------
179local function tput(putt)
180 local ftp = socket.ftp.open(putt.host, putt.port)
181 ftp:greet()
182 ftp:login(putt.user, putt.password)
183 if putt.type then ftp:type(putt.type) end
184 ftp:pasv()
185 ftp:send(putt)
186 ftp:quit()
187 return ftp:close()
188end
174 189
175function put(putt) 190local default = {
191 path = "/",
192 scheme = "ftp"
193}
194
195local function parse(url)
196 local putt = socket.try(socket.url.parse(url, default))
197 socket.try(putt.scheme == "ftp", "invalid scheme '" .. putt.scheme .. "'")
198 socket.try(putt.host, "invalid host")
199 local pat = "^type=(.)$"
200 if putt.params then
201 putt.type = socket.skip(2, string.find(putt.params, pat))
202 socket.try(putt.type == "a" or putt.type == "i")
203 end
204 -- skip first backslash in path
205 putt.argument = string.sub(putt.path, 2)
206 return putt
176end 207end
177 208
178function get(gett) 209local function sput(url, body)
210 local putt = parse(url)
211 putt.source = ltn12.source.string(body)
212 return tput(putt)
179end 213end
180 214
215put = socket.protect(function(putt, body)
216 if type(putt) == "string" then return sput(putt, body)
217 else return tput(putt) end
218end)
219
220local function tget(gett)
221 local ftp = socket.ftp.open(gett.host, gett.port)
222 ftp:greet()
223 ftp:login(gett.user, gett.password)
224 if gett.type then ftp:type(gett.type) end
225 ftp:pasv()
226 ftp:receive(gett)
227 ftp:quit()
228 return ftp:close()
229end
230
231local function sget(url, body)
232 local gett = parse(url)
233 local t = {}
234 gett.sink = ltn12.sink.table(t)
235 tget(gett)
236 return table.concat(t)
237end
238
239get = socket.protect(function(gett)
240 if type(gett) == "string" then return sget(gett, body)
241 else return tget(gett) end
242end)
243
181return ftp 244return ftp