diff options
Diffstat (limited to 'src/ftp.lua')
-rw-r--r-- | src/ftp.lua | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/src/ftp.lua b/src/ftp.lua index 9902c88..4529acd 100644 --- a/src/ftp.lua +++ b/src/ftp.lua | |||
@@ -8,13 +8,15 @@ | |||
8 | ----------------------------------------------------------------------------- | 8 | ----------------------------------------------------------------------------- |
9 | -- Declare module and import dependencies | 9 | -- Declare module and import dependencies |
10 | ----------------------------------------------------------------------------- | 10 | ----------------------------------------------------------------------------- |
11 | local base = require("base") | ||
12 | local table = require("table") | ||
13 | local string = require("string") | ||
14 | local math = require("math") | ||
11 | local socket = require("socket") | 15 | local socket = require("socket") |
12 | local url = require("socket.url") | 16 | local url = require("socket.url") |
13 | local tp = require("socket.tp") | 17 | local tp = require("socket.tp") |
14 | |||
15 | local ltn12 = require("ltn12") | 18 | local ltn12 = require("ltn12") |
16 | 19 | local ftp = module("socket.ftp") | |
17 | module("socket.ftp") | ||
18 | 20 | ||
19 | ----------------------------------------------------------------------------- | 21 | ----------------------------------------------------------------------------- |
20 | -- Program constants | 22 | -- Program constants |
@@ -35,7 +37,7 @@ local metat = { __index = {} } | |||
35 | 37 | ||
36 | function open(server, port) | 38 | function open(server, port) |
37 | local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT)) | 39 | local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT)) |
38 | local f = setmetatable({ tp = tp }, metat) | 40 | local f = base.setmetatable({ tp = tp }, metat) |
39 | -- make sure everything gets closed in an exception | 41 | -- make sure everything gets closed in an exception |
40 | f.try = socket.newtry(function() f:close() end) | 42 | f.try = socket.newtry(function() f:close() end) |
41 | return f | 43 | return f |
@@ -102,7 +104,8 @@ function metat.__index:send(sendt) | |||
102 | -- we just get the data connection into self.data | 104 | -- we just get the data connection into self.data |
103 | if self.pasvt then self:pasvconnect() end | 105 | if self.pasvt then self:pasvconnect() end |
104 | -- get the transfer argument and command | 106 | -- get the transfer argument and command |
105 | local argument = sendt.argument or string.gsub(sendt.path, "^/", "") | 107 | local argument = sendt.argument or |
108 | url.unescape(string.gsub(sendt.path or "", "^/", "")) | ||
106 | if argument == "" then argument = nil end | 109 | if argument == "" then argument = nil end |
107 | local command = sendt.command or "stor" | 110 | local command = sendt.command or "stor" |
108 | -- send the transfer command and check the reply | 111 | -- send the transfer command and check the reply |
@@ -134,7 +137,8 @@ end | |||
134 | function metat.__index:receive(recvt) | 137 | function metat.__index:receive(recvt) |
135 | self.try(self.pasvt or self.server, "need port or pasv first") | 138 | self.try(self.pasvt or self.server, "need port or pasv first") |
136 | if self.pasvt then self:pasvconnect() end | 139 | if self.pasvt then self:pasvconnect() end |
137 | local argument = recvt.argument or string.gsub(recvt.path, "^/", "") | 140 | local argument = recvt.argument or |
141 | url.unescape(string.gsub(recvt.path or "", "^/", "")) | ||
138 | if argument == "" then argument = nil end | 142 | if argument == "" then argument = nil end |
139 | local command = recvt.command or "retr" | 143 | local command = recvt.command or "retr" |
140 | self.try(self.tp:command(command, argument)) | 144 | self.try(self.tp:command(command, argument)) |
@@ -182,7 +186,19 @@ end | |||
182 | ----------------------------------------------------------------------------- | 186 | ----------------------------------------------------------------------------- |
183 | -- High level FTP API | 187 | -- High level FTP API |
184 | ----------------------------------------------------------------------------- | 188 | ----------------------------------------------------------------------------- |
189 | function override(t) | ||
190 | if t.url then | ||
191 | u = url.parse(t.url) | ||
192 | for i,v in base.pairs(t) do | ||
193 | u[i] = v | ||
194 | end | ||
195 | return u | ||
196 | else return t end | ||
197 | end | ||
198 | |||
185 | local function tput(putt) | 199 | local function tput(putt) |
200 | putt = override(putt) | ||
201 | socket.try(putt.host, "missing hostname") | ||
186 | local f = open(putt.host, putt.port) | 202 | local f = open(putt.host, putt.port) |
187 | f:greet() | 203 | f:greet() |
188 | f:login(putt.user, putt.password) | 204 | f:login(putt.user, putt.password) |
@@ -201,8 +217,8 @@ local default = { | |||
201 | 217 | ||
202 | local function parse(u) | 218 | local function parse(u) |
203 | local t = socket.try(url.parse(u, default)) | 219 | local t = socket.try(url.parse(u, default)) |
204 | socket.try(t.scheme == "ftp", "invalid scheme '" .. t.scheme .. "'") | 220 | socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") |
205 | socket.try(t.host, "invalid host") | 221 | socket.try(t.host, "missing hostname") |
206 | local pat = "^type=(.)$" | 222 | local pat = "^type=(.)$" |
207 | if t.params then | 223 | if t.params then |
208 | t.type = socket.skip(2, string.find(t.params, pat)) | 224 | t.type = socket.skip(2, string.find(t.params, pat)) |
@@ -219,11 +235,13 @@ local function sput(u, body) | |||
219 | end | 235 | end |
220 | 236 | ||
221 | put = socket.protect(function(putt, body) | 237 | put = socket.protect(function(putt, body) |
222 | if type(putt) == "string" then return sput(putt, body) | 238 | if base.type(putt) == "string" then return sput(putt, body) |
223 | else return tput(putt) end | 239 | else return tput(putt) end |
224 | end) | 240 | end) |
225 | 241 | ||
226 | local function tget(gett) | 242 | local function tget(gett) |
243 | gett = override(gett) | ||
244 | socket.try(gett.host, "missing hostname") | ||
227 | local f = open(gett.host, gett.port) | 245 | local f = open(gett.host, gett.port) |
228 | f:greet() | 246 | f:greet() |
229 | f:login(gett.user, gett.password) | 247 | f:login(gett.user, gett.password) |
@@ -242,7 +260,22 @@ local function sget(u) | |||
242 | return table.concat(t) | 260 | return table.concat(t) |
243 | end | 261 | end |
244 | 262 | ||
263 | command = socket.protect(function(cmdt) | ||
264 | cmdt = override(cmdt) | ||
265 | socket.try(cmdt.host, "missing hostname") | ||
266 | socket.try(cmdt.command, "missing command") | ||
267 | local f = open(cmdt.host, cmdt.port) | ||
268 | f:greet() | ||
269 | f:login(cmdt.user, cmdt.password) | ||
270 | f.try(f.tp:command(cmdt.command, cmdt.argument)) | ||
271 | if cmdt.check then f.try(f.tp:check(cmdt.check)) end | ||
272 | f:quit() | ||
273 | return f:close() | ||
274 | end) | ||
275 | |||
245 | get = socket.protect(function(gett) | 276 | get = socket.protect(function(gett) |
246 | if type(gett) == "string" then return sget(gett) | 277 | if base.type(gett) == "string" then return sget(gett) |
247 | else return tget(gett) end | 278 | else return tget(gett) end |
248 | end) | 279 | end) |
280 | |||
281 | base.setmetatable(ftp, nil) | ||