|
|
@@ -0,0 +1,121 @@ |
|
|
|
local net = require "minitel" |
|
|
|
local dl = {} |
|
|
|
dl.protos = {} |
|
|
|
|
|
|
|
-- Stolen from the old exec/fget |
|
|
|
local function parseURL(url) |
|
|
|
local proto,addr = url:match("(.-)://(.+)") |
|
|
|
addr = addr or url |
|
|
|
local hp, path = addr:match("(.-)(/.*)") |
|
|
|
hp, path = hp or addr, path or "/" |
|
|
|
local host, port = hp:match("(.+):(.+)") |
|
|
|
host = host or hp |
|
|
|
return proto, host, port, path |
|
|
|
end |
|
|
|
|
|
|
|
function dl.protos.fget(host, optPort, path, dest) -- string string string number -- boolean -- Downloads path from host (on optPort or 70), printing the directory listing, or saving the file to dest. |
|
|
|
local socket = assert(net.open(host, optPort or 70)) |
|
|
|
socket:write(string.format("t%s\n", path)) |
|
|
|
local status |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
status = socket:read(1) |
|
|
|
until status ~= "" |
|
|
|
|
|
|
|
if status == "d" then |
|
|
|
io.write("Directory Listing:\n") |
|
|
|
local tmp = "" |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
tmp = socket:read("*a") |
|
|
|
|
|
|
|
io.write(tmp) |
|
|
|
until socket.state == "closed" and tmp == "" |
|
|
|
|
|
|
|
return true |
|
|
|
elseif status == "y" then |
|
|
|
if not dest then |
|
|
|
error("Must provide local path to save remote files.") |
|
|
|
end |
|
|
|
|
|
|
|
io.write(string.format("Saving %s to %s...\n", path, dest)) |
|
|
|
local f = assert(io.open(dest, "wb")) |
|
|
|
local tmp = "" |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
tmp = socket:read("*a") |
|
|
|
|
|
|
|
f:write(tmp) |
|
|
|
until socket.state == "closed" and tmp == "" |
|
|
|
|
|
|
|
f:close() |
|
|
|
print("Done.") |
|
|
|
|
|
|
|
return true |
|
|
|
else |
|
|
|
local err, tmp = "", "" |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
tmp = socket:read("*a") |
|
|
|
|
|
|
|
err = err .. tmp |
|
|
|
until socket.state == "closed" and tmp == "" |
|
|
|
|
|
|
|
error(string.format("Got error from remote host: %s", err)) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function dl.protos.http(host, optPort, path, dest, url) -- string string string number -- boolean -- Downloads *url* to *dest* via the internet card, if available. |
|
|
|
if not component.list("internet")() then |
|
|
|
local proto,host,sPort,path = parseURL(url) |
|
|
|
local proxy = os.getenv(proto:upper().."_PROXY") |
|
|
|
if not proxy and fs.exists("/boot/cfg/"..proto.."_proxy") then |
|
|
|
local f = io.open("/boot/cfg/"..proto.."_proxy","rb") |
|
|
|
proxy = f:read() |
|
|
|
f:close() |
|
|
|
end |
|
|
|
if not proxy then error("No internet card or HTTP(S) proxy available") end |
|
|
|
if optPort then host=string.format("%s:%i",host,optPort) end |
|
|
|
return dl.wget(string.format("%s/%s%s",proxy,host,path)) |
|
|
|
end |
|
|
|
if not dest then |
|
|
|
error("Must provide local path to save remote files.") |
|
|
|
end |
|
|
|
local R,r=component.invoke(component.list("internet")(),"request",url) |
|
|
|
if not R then error(r) end |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
until R.finishConnect() |
|
|
|
local code, message, headers = R.response() |
|
|
|
if code > 299 or code < 200 then |
|
|
|
return false, code, message |
|
|
|
end |
|
|
|
local f=io.open(dest,"wb") |
|
|
|
if not f then error("Unable to open file "..dest) end |
|
|
|
io.write(string.format("Saving %s to %s...\n", url, dest)) |
|
|
|
repeat |
|
|
|
coroutine.yield() |
|
|
|
ns = R.read(2048) |
|
|
|
f:write(ns or "") |
|
|
|
until not ns |
|
|
|
f:close() |
|
|
|
print("Done.") |
|
|
|
return true |
|
|
|
end |
|
|
|
dl.protos.https = dl.protos.http |
|
|
|
|
|
|
|
function dl.wget(remotePath, dest) -- string string -- -- Downloads from remote *remotePath* to *dest* |
|
|
|
local proto, host, sPort, path = parseURL(remotePath) |
|
|
|
if dl.protos[proto] then |
|
|
|
local port |
|
|
|
if sPort then |
|
|
|
port = tonumber(sPort) |
|
|
|
end |
|
|
|
|
|
|
|
dl.protos[proto](host, port, path, dest, remotePath) |
|
|
|
else |
|
|
|
error("Unsupported protocol: " .. tostring(proto)) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
return setmetatable(dl,{__call=function(_,path,dest) return dl.wget(path,dest) end}) |