Grab v2.4.3-alpha

Support router and proxy settings.
Fix /etc/grab/grab.version not updated issue.
Prepare for trusted providers.
This commit is contained in:
Kirigaya Kazuto 2018-12-03 15:24:35 +08:00
parent 0a3579efd3
commit 8e43cee6a0

156
grab.lua
View File

@ -9,7 +9,7 @@ local event=require('event')
local term=require('term') local term=require('term')
local args,options=shell.parse(...) local args,options=shell.parse(...)
local grab_version="Grab v2.4.2-alpha" local grab_version="Grab v2.4.3-alpha"
local usage_text=[===[Grab - Official OpenComputerScripts Installer local usage_text=[===[Grab - Official OpenComputerScripts Installer
Usage: Usage:
@ -18,8 +18,10 @@ Options:
--cn Use mirror site in China. By default grab will download from Github. This might be useful for only official packages. --cn Use mirror site in China. By default grab will download from Github. This might be useful for only official packages.
--help Display this help page. --help Display this help page.
--version Display version and exit. --version Display version and exit.
--proxy=<Proxy File> Given a proxy file which will be loaded and returns a proxy function like: --router=<Router File> Given a file which will be loaded and returns a route function like:
function(RepoName: string, Branch: string ,FileAddress: string): string function(RepoName: string, Branch: string ,FileAddress: string): string
--proxy=<Proxy File> Given a file which will be loaded and returns a proxy function like:
function(Url : string): boolean, string
--skip-install Library installers will not be executed. --skip-install Library installers will not be executed.
--refuse-license <License> Set refused license. Separate multiple values with ',' --refuse-license <License> Set refused license. Separate multiple values with ','
--accept-license <License> Set accepted license. Separate multiple values with ',' --accept-license <License> Set accepted license. Separate multiple values with ','
@ -49,10 +51,21 @@ Notice:
A package is considered to be official only if it does not specified repo and proxy. Official packages usually only depend on official packages. A package is considered to be official only if it does not specified repo and proxy. Official packages usually only depend on official packages.
You can also install packages from unofficial program provider with Grab, but Grab will not check its security. You can also install packages from unofficial program provider with Grab, but Grab will not check its security.
Notice that override of official packages is not allowed. Notice that override of official packages is not allowed.
Router and Proxy
route_func(RepoName: string, Branch: string ,FileAddress: string): string
A route function takes repo, branch and file address as arguments, and returns a resolved url.
It can be used to boost downloading by redirecting requests to mirror site.
As router functions can be used to redirect requests, Grab will give an warning if --router option presents.
proxy_func(Url : string): boolean, string
A proxy function takes url as argument, and returns at least 2 values.
It can be used to handle different protocols or low-level network operations like downloading files via SOCKS5 proxy or in-game modem network.
The first returned value is true if content is downloaded successfully. Thus, the second value will be the downloaded content.
If the first value is false, the downloading is failed. The second value will then be the error message.
If proxy functions throw an error, Grab will try the default downloader.
]===] ]===]
-- Install man document -- Install man document
if(not filesystem.exists("/etc/grab/grab.version")) then local function _update_document()
local f=io.open("/etc/grab/grab.version","w") local f=io.open("/etc/grab/grab.version","w")
if(f) then if(f) then
f:write(grab_version) f:write(grab_version)
@ -63,17 +76,16 @@ if(not filesystem.exists("/etc/grab/grab.version")) then
f:write(usage_text) f:write(usage_text)
f:close() f:close()
end end
end
if(not filesystem.exists("/etc/grab/grab.version")) then
_update_document()
else else
local f=io.open("/etc/grab/grab.version","r") local f=io.open("/etc/grab/grab.version","r")
if(f) then if(f) then
local installed_version=f:read("a") local installed_version=f:read("a")
f:close() f:close()
if(installed_version~=grab_version) then if(installed_version~=grab_version) then
f=io.open("/usr/man/grab","w") _update_document()
if(f) then
f:write(usage_text)
f:close()
end
end end
end end
end end
@ -95,7 +107,8 @@ local valid_options={
["cn"]=true, ["cn"]=true,
["help"]=true, ["help"]=true,
["version"]=true, ["version"]=true,
["proxy"]=true, ["router"]="string",
["proxy"]="string",
["skip-install"]=true, ["skip-install"]=true,
["refuse-license"]=true, ["refuse-license"]=true,
["accept-license"]=true ["accept-license"]=true
@ -112,26 +125,23 @@ local valid_command={
["download"]=true ["download"]=true
} }
local nOptions=0
for k,v in pairs(options) do for k,v in pairs(options) do
if(not valid_options[k]) then if(not valid_options[k]) then
if(string.len(k)>1) then print("Unknown option: --" .. k) if(string.len(k)>1) then
else print("Unknown option: -" .. k) end print("Unknown option: --" .. k)
else
print("Unknown option: -" .. k)
end
return
elseif(type(valid_options[k])=="string") then
if(type(options[k])~=valid_options[k]) then
print("Invalid option type: Option type of --" .. k .. " should be " .. valid_options[k])
return return
end end
nOptions=nOptions+1
end
local function check_internet()
if(component.internet==nil) then
print("Error: An internet card is required to run this program.")
return false
else
return true
end end
end end
if( (#args<1 and nOptions<1) or options["help"]) then if( (#args<1 and not next(options)) or options["help"]) then
show_usage() show_usage()
return return
end end
@ -141,10 +151,21 @@ if(options["version"]) then
return return
end end
local function download(url) local function check_internet()
if(component.internet==nil) then if(not options["proxy"] and not component.internet) then
error("This program requires an Internet card.") print("Error: An internet card is required to run this program.")
return false
else
-- If proxy presents, internet card is not required. Programs may handle network requests via in-game modem network.
return true
end end
end
local function default_downloader(url)
if(not component.internet) then
return false,"No internet card found."
end
local handle=component.internet.request(url) local handle=component.internet.request(url)
while true do while true do
local ret,err=handle.finishConnect() local ret,err=handle.finishConnect()
@ -160,18 +181,26 @@ local function download(url)
end end
end end
end end
local code=handle.response() local code=handle.response()
if(code~=200) then
handle.close()
return false,"Response code " .. code .. " is not 200."
end
local result='' local result=''
while true do while true do
local temp=handle.read() local temp=handle.read()
if(temp==nil) then break end if(temp==nil) then break end
result=result .. temp result=result .. temp
end end
handle.close() handle.close()
return true,result,code return true,result
end end
local UrlGenerator local UrlGenerator
if(not options["proxy"]) then if(not options["router"]) then
if(not options["cn"]) then if(not options["cn"]) then
UrlGenerator=function(RepoName,Branch,FileAddress) UrlGenerator=function(RepoName,Branch,FileAddress)
return "https://raw.githubusercontent.com/" .. RepoName .. "/" .. Branch .. "/" .. FileAddress return "https://raw.githubusercontent.com/" .. RepoName .. "/" .. Branch .. "/" .. FileAddress
@ -181,26 +210,67 @@ if(not options["proxy"]) then
return "http://kiritow.com:3000/" .. RepoName .. "/raw/" .. Branch .. "/" .. FileAddress return "http://kiritow.com:3000/" .. RepoName .. "/raw/" .. Branch .. "/" .. FileAddress
end end
end end
else
local ok,err=pcall(function()
local fn,xerr=loadfile(options["router"])
if(not fn) then
error(xerr)
else
UrlGenerator=fn()
if(type(UrlGenerator)~="function") then
error("Loaded router returns " .. type(UrlGenerator) .. " instead of a function.")
end
end
end)
if(not ok) then
print("Unable to load router file: " .. err)
return
end
print("[WARN] Router presents. Be aware of security issues.")
end
local download
if(not options["proxy"]) then
download=default_downloader
else else
local ok,err=pcall(function() local ok,err=pcall(function()
local fn,xerr=loadfile(options["proxy"]) local fn,xerr=loadfile(options["proxy"])
if(not fn) then error(xerr) if(not fn) then
else UrlGenerator=fn() end error(xerr)
else
download=fn()
if(type(download)~="function") then
error("Loaded proxy returns " .. type(download) .. " instead of a function.")
end
end
end) end)
if(not ok) then if(not ok) then
print("Unable to load proxy file: " .. err) print("Unable to load proxy file: " .. err)
return return
end end
print("[WARN] Proxy presents. Be aware of security issues.")
end end
local function IsOfficial(tb_package) local function IsOfficial(tb_package)
if(tb_package.repo==nil and tb_package.proxy==nil) then if(tb_package.repo==nil and
tb_package.proxy==nil and
tb_package.provider==nil
) then
return true return true
else else
return false return false
end end
end end
local function IsTrusted(tb_package)
if(tb_package.provider) then
-- TODO: Check Provider by comparing with online trusted list.
else
return false
end
end
local db_dirs={"/etc/grab",".grab","/tmp/.grab"} local db_dirs={"/etc/grab",".grab","/tmp/.grab"}
local db_positions={"/etc/grab/programs.info",".grab/programs.info","/tmp/.grab/programs.info"} local db_positions={"/etc/grab/programs.info",".grab/programs.info","/tmp/.grab/programs.info"}
@ -355,11 +425,9 @@ if(args[1]=="update") then
print("Updating programs info....") print("Updating programs info....")
io.write("Downloading... ") io.write("Downloading... ")
local ok,result,code=download(UrlGenerator("Kiritow/OpenComputerScripts","master","programs.info")) local ok,result=download(UrlGenerator("Kiritow/OpenComputerScripts","master","programs.info"))
if(not ok) then if(not ok) then
print("[Failed] " .. result) print("[Failed] " .. result)
elseif(code~=200) then
print("[Failed] response code " .. code .. " is not 200.")
else else
print("[OK]") print("[OK]")
io.write("Validating... ") io.write("Validating... ")
@ -422,11 +490,9 @@ if(args[1]=="verify") then
end end
else else
print("Downloading from " .. url) print("Downloading from " .. url)
local ok,result,code=download(url) local ok,result=download(url)
if(not ok) then if(not ok) then
print("[Download Failed] " .. result) print("[Download Failed] " .. result)
elseif(code~=200) then
print("[Download Failed] Response code is not 200 but " .. code)
else else
local t,err=CheckAndLoad("return " .. result) local t,err=CheckAndLoad("return " .. result)
if(t) then if(t) then
@ -481,11 +547,9 @@ if(args[1]=="add") then
end end
else else
print("Downloading from " .. url) print("Downloading from " .. url)
local ok,result,code=download(url) local ok,result=download(url)
if(not ok) then if(not ok) then
print("[Download Failed] " .. result) print("[Download Failed] " .. result)
elseif(code~=200) then
print("[Download Failed] Response code is not 200 but " .. code)
else else
local t,err=CheckAndLoad("return " .. result) local t,err=CheckAndLoad("return " .. result)
if(t) then if(t) then
@ -635,8 +699,8 @@ if(args[1]=="install") then
else else
-- Download the license and show it to user. -- Download the license and show it to user.
print("Downloading license " .. db[this_lib].license.name .. " for library " .. this_lib .. " from: " .. db[this_lib].license.url) print("Downloading license " .. db[this_lib].license.name .. " for library " .. this_lib .. " from: " .. db[this_lib].license.url)
local ok,result,code=download(db[this_lib].license.url) local ok,result=download(db[this_lib].license.url)
if(not ok or code~=200) then if(not ok) then
print("[Download Failed] Unable to download license.") print("[Download Failed] Unable to download license.")
return return
end end
@ -717,13 +781,10 @@ if(args[1]=="install") then
else else
this_url=UrlGenerator(db[this_lib].repo or "Kiritow/OpenComputerScripts",db[this_lib].branch or "master",toDownload) this_url=UrlGenerator(db[this_lib].repo or "Kiritow/OpenComputerScripts",db[this_lib].branch or "master",toDownload)
end end
local ok,result,code=download(this_url) local ok,result=download(this_url)
if(not ok) then if(not ok) then
print("[Download Failed] " .. result) print("[Download Failed] " .. result)
return return
elseif(code~=200) then
print("[Download Failed] response code " .. code .. " is not 200.")
return
else else
count_byte=count_byte+string.len(result) count_byte=count_byte+string.len(result)
if(type(v)=="string") then if(type(v)=="string") then
@ -860,13 +921,10 @@ if(args[1]=="download") then
for i=1,#files,1 do for i=1,#files,1 do
io.write("[" .. i .. "/" .. #files .. "] Downloading " .. files[i] .. "...") io.write("[" .. i .. "/" .. #files .. "] Downloading " .. files[i] .. "...")
local ok,result,code=download(UrlGenerator("Kiritow/OpenComputerScripts","master",files[i])) local ok,result=download(UrlGenerator("Kiritow/OpenComputerScripts","master",files[i]))
if(not ok) then if(not ok) then
print("[Download Failed] " .. result) print("[Download Failed] " .. result)
return return
elseif(code~=200) then
print("[Download Failed] response code " .. code .. " is not 200.")
return
else else
local f,ferr=io.open(files[i],"w") local f,ferr=io.open(files[i],"w")
if(not f) then if(not f) then