--CCPT - ComputerCraft Packaging Tool if not http then error("HTTP API MUST be enabled to use this program") end --Pseudo enums local validator = {ok = 0, installed = 1, file_conflict = 2} ---UTILITIES local function CGetS(file,name) local _cfg = fs.open(file,"r") if not _cfg then error("Could not open configuration file: "..file) end local x = true; while x do local line = _cfg.readLine() if line == nil then x = false; else local side = false local prop = "" local val = "" for a=1,#line do if line:sub(a,a) == '=' then side = true elseif side then val = val .. line:sub(a,a) else prop = prop .. line:sub(a,a) end end if prop == name then _cfg.close() return val end end end _cfg.close() end local function CGetN(file,name) return tonumber(CGetS(file,name)) end local function download(file, url) local res = http.get(url) if res then if file ~= nil then local fhnd = fs.open(file, "w"); if fhnd then fhnd.write(res.readAll()) fhnd.close() return res.readAll() else res.close() error("Could not open "..file.." for writing") end else return res.readAll() end else error("Download failed for: "..url) end res.close() end function split(text,splitter) local rt = {} local act = "" for x=1,#text do if text:sub(x,x+#splitter-1) == splitter then rt[#rt+1]=act act="" else act = act .. text:sub(x,x) end end if act ~= "" then rt[#rt+1] = act end return rt; end ---Intarnal functions local function update_list() local sync = CGetS("/etc/ccpt/config","master") if sync then download("/etc/ccpt/list",sync) else error("Update failed: master server not set!") end end local function base_find(name) local base = fs.open("/etc/ccpt/list","r") if not base then error("Could not open base file: /etc/ccpt/list") end local x = true; while x do local line = base.readLine() if line == nil then x = false; else local entry = split(line,";") if entry[1] == "p" then if entry[2] == name then local ret = {name=entry[2],url=entry[4],version=tonumber(entry[3])} return ret end end end end end local function validate(pname,header) local instbase = fs.open("/etc/ccpt/installed","r") if instbase then local x = true while x do local tline = instbase.readLine() if tline == nil then x = false else if pname == split(tline,";")[1] then return validator.installed end end end end --local filebase = fs.open("/etc/ccpt/files","r") lhead = split(header,"\n") local x = 1 for x = 1, #lhead do if split(lhead[x],";")[1] == "f" then if fs.exists(split(lhead[x],";")[2]) then return validator.file_conflict end end end return validator.ok end local function download_files(url,header) lhead = split(header,"\n") local x = 1 for x = 1, #lhead do if split(lhead[x],";")[1] == "f" then download(split(lhead[x],";")[2],url..split(lhead[x],";")[2]) end end end ---MAIN CODE local argv = {...} if argv[1] == "init" then print("Installing directories") fs.makeDir("/etc/") fs.makeDir("/etc/ccpt") fs.makeDir("/bin/") fs.makeDir("/usr/") fs.makeDir("/usr/bin") fs.makeDir("/usr/lib") fs.makeDir("/usr/share") print("Downloading default config") download("/etc/ccpt/config","http://cc.nativehttp.org/fresh/config") print("Updating package list") update_list() elseif argv[1] == "update" then print("Updating package list") update_list() elseif argv[1] == "install" then if argv[2] == nil then print("Usage: ccpk install [name]") else print("Reading Database") local entry = base_find(argv[2]) if entry then print("Downloading package header") local header = download(nil, entry.url..entry.name.."/index") print("Checking for conflicts") local vres = validate(entry.name,header) if vres == validator.ok then print("Downloading files") download_files(entry.url,header) elseif vres == validator.installed then print("Package already installed") else print("File conflict detected!") end else print("Package not found!") end end end