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 coroutine.yield() until R.finishConnect() 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})