|
- 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
- print("Internet card unavailable, falling back to proxy "..proxy)
- if optPort then host=string.format("%s:%i",host,optPort) end
- return dl.wget(string.format("%s/%s%s",proxy,host,path),dest)
- 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
- ok, err = R.finishConnect()
- if type(ok) ~= "boolean" then
- if err == url then
- return 404, "This is a bug in OC, I think?"
- end
- return -1, err or "Connection Error"
- end
- coroutine.yield()
- until ok
- local code, messsage, headers
- repeat
- coroutine.yield()
- code, message, headers = R.response()
- until code or message
- 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()
- 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})
|