diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-03-20 00:24:44 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-03-20 00:24:44 +0000 |
| commit | 53857360bb1ca9cd2080b69d930763ae59db9b06 (patch) | |
| tree | 6c1bc6d6462695cf9048801b2244f7fd0cd21ad5 /src/ftp.lua | |
| parent | 7da19138e37c4e0123860f1fecbceb80c3d2627d (diff) | |
| download | luasocket-53857360bb1ca9cd2080b69d930763ae59db9b06.tar.gz luasocket-53857360bb1ca9cd2080b69d930763ae59db9b06.tar.bz2 luasocket-53857360bb1ca9cd2080b69d930763ae59db9b06.zip | |
Finish port to Lua 5. Everything is working fine.
Still doesn't work in Windows.
Diffstat (limited to 'src/ftp.lua')
| -rw-r--r-- | src/ftp.lua | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/src/ftp.lua b/src/ftp.lua index 1fa48f7..f6fffbb 100644 --- a/src/ftp.lua +++ b/src/ftp.lua | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | ----------------------------------------------------------------------------- | 8 | ----------------------------------------------------------------------------- |
| 9 | 9 | ||
| 10 | local Public, Private = {}, {} | 10 | local Public, Private = {}, {} |
| 11 | FTP = Public | 11 | socket.ftp = Public |
| 12 | 12 | ||
| 13 | ----------------------------------------------------------------------------- | 13 | ----------------------------------------------------------------------------- |
| 14 | -- Program constants | 14 | -- Program constants |
| @@ -47,7 +47,7 @@ end | |||
| 47 | ----------------------------------------------------------------------------- | 47 | ----------------------------------------------------------------------------- |
| 48 | function Private.try_receive(...) | 48 | function Private.try_receive(...) |
| 49 | local sock = arg[1] | 49 | local sock = arg[1] |
| 50 | local data, err = call(sock.receive, arg) | 50 | local data, err = sock.receive(unpack(arg)) |
| 51 | if err then sock:close() end | 51 | if err then sock:close() end |
| 52 | return data, err | 52 | return data, err |
| 53 | end | 53 | end |
| @@ -64,9 +64,9 @@ function Private.get_pasv(pasv) | |||
| 64 | local a, b, c, d, p1, p2, _ | 64 | local a, b, c, d, p1, p2, _ |
| 65 | local ip, port | 65 | local ip, port |
| 66 | _,_, a, b, c, d, p1, p2 = | 66 | _,_, a, b, c, d, p1, p2 = |
| 67 | strfind(pasv, "(%d*),(%d*),(%d*),(%d*),(%d*),(%d*)") | 67 | string.find(pasv, "(%d*),(%d*),(%d*),(%d*),(%d*),(%d*)") |
| 68 | if not (a and b and c and d and p1 and p2) then return nil, nil end | 68 | if not (a and b and c and d and p1 and p2) then return nil, nil end |
| 69 | ip = format("%d.%d.%d.%d", a, b, c, d) | 69 | ip = string.format("%d.%d.%d.%d", a, b, c, d) |
| 70 | port = tonumber(p1)*256 + tonumber(p2) | 70 | port = tonumber(p1)*256 + tonumber(p2) |
| 71 | return ip, port | 71 | return ip, port |
| 72 | end | 72 | end |
| @@ -100,13 +100,13 @@ function Private.get_answer(control) | |||
| 100 | local line, err = Private.try_receive(control) | 100 | local line, err = Private.try_receive(control) |
| 101 | local answer = line | 101 | local answer = line |
| 102 | if err then return nil, err end | 102 | if err then return nil, err end |
| 103 | _,_, code, sep = strfind(line, "^(%d%d%d)(.)") | 103 | _,_, code, sep = string.find(line, "^(%d%d%d)(.)") |
| 104 | if not code or not sep then return nil, answer end | 104 | if not code or not sep then return nil, answer end |
| 105 | if sep == "-" then -- answer is multiline | 105 | if sep == "-" then -- answer is multiline |
| 106 | repeat | 106 | repeat |
| 107 | line, err = Private.try_receive(control) | 107 | line, err = Private.try_receive(control) |
| 108 | if err then return nil, err end | 108 | if err then return nil, err end |
| 109 | _,_, lastcode, sep = strfind(line, "^(%d%d%d)(.)") | 109 | _,_, lastcode, sep = string.find(line, "^(%d%d%d)(.)") |
| 110 | answer = answer .. "\n" .. line | 110 | answer = answer .. "\n" .. line |
| 111 | until code == lastcode and sep == " " -- answer ends with same code | 111 | until code == lastcode and sep == " " -- answer ends with same code |
| 112 | end | 112 | end |
| @@ -126,8 +126,8 @@ function Private.check_answer(control, success) | |||
| 126 | local answer, code = Private.get_answer(control) | 126 | local answer, code = Private.get_answer(control) |
| 127 | if not answer then return nil, code end | 127 | if not answer then return nil, code end |
| 128 | if type(success) ~= "table" then success = {success} end | 128 | if type(success) ~= "table" then success = {success} end |
| 129 | for i = 1, getn(success) do | 129 | for _, s in ipairs(success) do |
| 130 | if code == success[i] then | 130 | if code == s then |
| 131 | return code, answer | 131 | return code, answer |
| 132 | end | 132 | end |
| 133 | end | 133 | end |
| @@ -213,13 +213,13 @@ function Private.port(control) | |||
| 213 | local code, answer | 213 | local code, answer |
| 214 | local server, ctl_ip | 214 | local server, ctl_ip |
| 215 | ctl_ip, answer = control:getsockname() | 215 | ctl_ip, answer = control:getsockname() |
| 216 | server, answer = bind(ctl_ip, 0) | 216 | server, answer = socket.bind(ctl_ip, 0) |
| 217 | server:timeout(Public.TIMEOUT) | 217 | server:timeout(Public.TIMEOUT) |
| 218 | local ip, p, ph, pl | 218 | local ip, p, ph, pl |
| 219 | ip, p = server:getsockname() | 219 | ip, p = server:getsockname() |
| 220 | pl = mod(p, 256) | 220 | pl = math.mod(p, 256) |
| 221 | ph = (p - pl)/256 | 221 | ph = (p - pl)/256 |
| 222 | local arg = gsub(format("%s,%d,%d", ip, ph, pl), "%.", ",") | 222 | local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",") |
| 223 | code, answer = Private.command(control, "port", arg, {200}) | 223 | code, answer = Private.command(control, "port", arg, {200}) |
| 224 | if not code then | 224 | if not code then |
| 225 | server:close() | 225 | server:close() |
| @@ -321,7 +321,7 @@ function Private.send_indirect(data, send_cb, chunk, size) | |||
| 321 | data:close() | 321 | data:close() |
| 322 | return err | 322 | return err |
| 323 | end | 323 | end |
| 324 | sent = sent + strlen(chunk) | 324 | sent = sent + string.len(chunk) |
| 325 | if sent >= size then break end | 325 | if sent >= size then break end |
| 326 | chunk, size = send_cb() | 326 | chunk, size = send_cb() |
| 327 | end | 327 | end |
| @@ -374,7 +374,7 @@ end | |||
| 374 | ----------------------------------------------------------------------------- | 374 | ----------------------------------------------------------------------------- |
| 375 | function Private.change_type(control, params) | 375 | function Private.change_type(control, params) |
| 376 | local type, _ | 376 | local type, _ |
| 377 | _, _, type = strfind(params or "", "type=(.)") | 377 | _, _, type = string.find(params or "", "type=(.)") |
| 378 | if type == "a" or type == "i" then | 378 | if type == "a" or type == "i" then |
| 379 | local code, err = Private.command(control, "type", type, {200}) | 379 | local code, err = Private.command(control, "type", type, {200}) |
| 380 | if not code then return err end | 380 | if not code then return err end |
| @@ -391,7 +391,7 @@ end | |||
| 391 | ----------------------------------------------------------------------------- | 391 | ----------------------------------------------------------------------------- |
| 392 | function Private.open(parsed) | 392 | function Private.open(parsed) |
| 393 | -- start control connection | 393 | -- start control connection |
| 394 | local control, err = connect(parsed.host, parsed.port) | 394 | local control, err = socket.connect(parsed.host, parsed.port) |
| 395 | if not control then return nil, err end | 395 | if not control then return nil, err end |
| 396 | -- make sure we don't block forever | 396 | -- make sure we don't block forever |
| 397 | control:timeout(Public.TIMEOUT) | 397 | control:timeout(Public.TIMEOUT) |
| @@ -423,7 +423,7 @@ end | |||
| 423 | -- err: error message if any | 423 | -- err: error message if any |
| 424 | ----------------------------------------------------------------------------- | 424 | ----------------------------------------------------------------------------- |
| 425 | function Private.change_dir(control, segment) | 425 | function Private.change_dir(control, segment) |
| 426 | local n = getn(segment) | 426 | local n = table.getn(segment) |
| 427 | for i = 1, n-1 do | 427 | for i = 1, n-1 do |
| 428 | local code, answer = Private.cwd(control, segment[i]) | 428 | local code, answer = Private.cwd(control, segment[i]) |
| 429 | if not code then return answer end | 429 | if not code then return answer end |
| @@ -443,7 +443,7 @@ end | |||
| 443 | function Private.upload(control, request, segment) | 443 | function Private.upload(control, request, segment) |
| 444 | local code, name, content_cb | 444 | local code, name, content_cb |
| 445 | -- get remote file name | 445 | -- get remote file name |
| 446 | name = segment[getn(segment)] | 446 | name = segment[table.getn(segment)] |
| 447 | if not name then | 447 | if not name then |
| 448 | control:close() | 448 | control:close() |
| 449 | return "Invalid file path" | 449 | return "Invalid file path" |
| @@ -472,7 +472,7 @@ function Private.download(control, request, segment) | |||
| 472 | is_directory = segment.is_directory | 472 | is_directory = segment.is_directory |
| 473 | content_cb = request.content_cb | 473 | content_cb = request.content_cb |
| 474 | -- get remote file name | 474 | -- get remote file name |
| 475 | name = segment[getn(segment)] | 475 | name = segment[table.getn(segment)] |
| 476 | if not name and not is_directory then | 476 | if not name and not is_directory then |
| 477 | control:close() | 477 | control:close() |
| 478 | return "Invalid file path" | 478 | return "Invalid file path" |
| @@ -498,7 +498,7 @@ end | |||
| 498 | -- parsed: a table with parsed components | 498 | -- parsed: a table with parsed components |
| 499 | ----------------------------------------------------------------------------- | 499 | ----------------------------------------------------------------------------- |
| 500 | function Private.parse_url(request) | 500 | function Private.parse_url(request) |
| 501 | local parsed = URL.parse_url(request.url, { | 501 | local parsed = socket.url.parse(request.url, { |
| 502 | host = "", | 502 | host = "", |
| 503 | user = "anonymous", | 503 | user = "anonymous", |
| 504 | port = 21, | 504 | port = 21, |
| @@ -521,9 +521,10 @@ end | |||
| 521 | -- Returns | 521 | -- Returns |
| 522 | -- dirs: a table with parsed directory components | 522 | -- dirs: a table with parsed directory components |
| 523 | ----------------------------------------------------------------------------- | 523 | ----------------------------------------------------------------------------- |
| 524 | function Private.parse_path(parsed) | 524 | function Private.parse_path(parsed_url) |
| 525 | local segment = URL.parse_path(parsed.path) | 525 | local segment = socket.url.parse_path(parsed_url.path) |
| 526 | segment.is_directory = segment.is_directory or (parsed.params == "type=d") | 526 | segment.is_directory = segment.is_directory or |
| 527 | (parsed_url.params == "type=d") | ||
| 527 | return segment | 528 | return segment |
| 528 | end | 529 | end |
| 529 | 530 | ||
| @@ -560,7 +561,7 @@ end | |||
| 560 | function Public.get_cb(request) | 561 | function Public.get_cb(request) |
| 561 | local parsed = Private.parse_url(request) | 562 | local parsed = Private.parse_url(request) |
| 562 | if parsed.scheme ~= "ftp" then | 563 | if parsed.scheme ~= "ftp" then |
| 563 | return format("unknown scheme '%s'", parsed.scheme) | 564 | return string.format("unknown scheme '%s'", parsed.scheme) |
| 564 | end | 565 | end |
| 565 | local control, err = Private.open(parsed) | 566 | local control, err = Private.open(parsed) |
| 566 | if not control then return err end | 567 | if not control then return err end |
| @@ -586,7 +587,7 @@ end | |||
| 586 | function Public.put_cb(request) | 587 | function Public.put_cb(request) |
| 587 | local parsed = Private.parse_url(request) | 588 | local parsed = Private.parse_url(request) |
| 588 | if parsed.scheme ~= "ftp" then | 589 | if parsed.scheme ~= "ftp" then |
| 589 | return format("unknown scheme '%s'", parsed.scheme) | 590 | return string.format("unknown scheme '%s'", parsed.scheme) |
| 590 | end | 591 | end |
| 591 | local control, err = Private.open(parsed) | 592 | local control, err = Private.open(parsed) |
| 592 | if not control then return err end | 593 | if not control then return err end |
| @@ -612,7 +613,7 @@ end | |||
| 612 | function Public.put(url_or_request, content) | 613 | function Public.put(url_or_request, content) |
| 613 | local request = Private.build_request(url_or_request) | 614 | local request = Private.build_request(url_or_request) |
| 614 | request.content_cb = function() | 615 | request.content_cb = function() |
| 615 | return content, strlen(content) | 616 | return content, string.len(content) |
| 616 | end | 617 | end |
| 617 | return Public.put_cb(request) | 618 | return Public.put_cb(request) |
| 618 | end | 619 | end |
| @@ -630,7 +631,7 @@ end | |||
| 630 | -- err: error message in case of error, nil otherwise | 631 | -- err: error message in case of error, nil otherwise |
| 631 | ----------------------------------------------------------------------------- | 632 | ----------------------------------------------------------------------------- |
| 632 | function Public.get(url_or_request) | 633 | function Public.get(url_or_request) |
| 633 | local cat = Concat.create() | 634 | local cat = socket.concat.create() |
| 634 | local request = Private.build_request(url_or_request) | 635 | local request = Private.build_request(url_or_request) |
| 635 | request.content_cb = function(chunk, err) | 636 | request.content_cb = function(chunk, err) |
| 636 | if chunk then cat:addstring(chunk) end | 637 | if chunk then cat:addstring(chunk) end |
