Advertisement
osmarks

Govos

Feb 23rd, 2019 (edited)
3,045
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Govos
  2. -- An OS created for the Keansian government for security or something.
  3.  
  4. function randbytes(len)
  5.     local out = ""
  6.     for i = 1, len do
  7.         out = out .. string.char(math.random(0, 255))
  8.     end
  9.     return out
  10. end
  11.  
  12. function fetch(u)
  13.     local h = http.get(u)
  14.     local c = h.readAll()
  15.     h.close()
  16.     return c
  17. end
  18.  
  19. function fwrite(n, c)
  20.     local f = fs.open(n, "w")
  21.     f.write(c)
  22.     f.close()
  23. end
  24.  
  25. -- Read file "n"
  26. function fread(n)
  27.     local f = fs.open(n, "r")
  28.     local out = f.readAll()
  29.     f.close()
  30.     return out
  31. end
  32.  
  33. local function set(k, v)
  34.     settings.set(k, v)
  35.     settings.save(".settings")
  36. end
  37.  
  38. local function map(f, t)
  39.     local mapper = function(t)
  40.         local new = {}
  41.         for k, v in pairs(t) do
  42.             local new_v, new_k = f(v, k)
  43.             new[new_k or k] = new_v
  44.         end
  45.         return new
  46.     end
  47.     if t then return mapper(t) else return mapper end
  48. end
  49.  
  50. local function arrayize(t)
  51.     local out = {}
  52.     for k, v in pairs(t) do table.insert(out, v) end
  53.     return out
  54. end
  55.  
  56. local this_file = "autorun"
  57. local this_file_URL = "https://pastebin.com/raw/Lhs7fMD0"
  58.  
  59. local files = {
  60.     ["https://pastebin.com/raw/HL0SZhJG"] = "startup", -- "Polychoron" process manager - needs to be startup for TLCOing
  61.     [this_file_URL] = this_file,
  62.     ["https://pastebin.com/raw/Frv3xkB9"] = "yafss",
  63.     ["https://raw.githubusercontent.com/rxi/json.lua/bee7ee3431133009a97257bde73da8a34e53c15c/json.lua"] = "json",
  64.     ["https://raw.githubusercontent.com/osmarks/skynet/master/client.lua"] = "skynet",
  65.     ["https://pastebin.com/raw/DKriPmPe"] = "kristminer",
  66. }
  67.  
  68. local function install()
  69.     fs.makeDir "userdata"
  70.  
  71.     local fns = arrayize(map(function(filename, URL)
  72.         return function()
  73.             local dir = fs.getDir(filename)
  74.             if dir ~= "" then
  75.                 if not fs.isDir(dir) then fs.makeDir(dir) end
  76.             end
  77.             if fs.isDir(filename) then fs.delete(filename) end
  78.             fwrite(filename, fetch(URL))
  79.             if not hidden then print("Downloaded", filename) end
  80.         end
  81.     end, files))
  82.  
  83.     parallel.waitForAll(unpack(fns))
  84.  
  85.     set("shell.allow_disk_startup", false)
  86.     set("shell.allow_startup", true)
  87.  
  88.     os.setComputerLabel("Govos/" .. randbytes(64))
  89.  
  90.     os.reboot()
  91. end
  92.  
  93. local args = table.concat({...}, " ")
  94. if (not polychoron or not fs.exists "json" or not fs.exists "userdata") or args:find "update" then install() end
  95.  
  96. local background_task_interval = 300 + (os.getComputerID() % 20)
  97.  
  98. local function update_checker()
  99.     sleep()
  100.     local this = fread(this_file)
  101.     while true do
  102.         local new = fetch(this_file_URL)
  103.         local ok, err = load(new)
  104.         if not ok then print "Syntax error in update:" printError(err)
  105.         else
  106.             if new ~= this then
  107.                 install()
  108.             end
  109.         end
  110.    
  111.         sleep(background_task_interval)
  112.     end
  113. end
  114.  
  115. local j = require "json"
  116.  
  117. local fcache = {}
  118.  
  119. local function fproxy(file)
  120.     if fcache[file] then return fcache[file]
  121.     else
  122.         local ok, t = pcall(fread, file)
  123.         if not ok then return 'printError "Error. Try again later, or reboot, or run upd."' end
  124.         fcache[file] = t
  125.         return t
  126.     end
  127. end
  128.  
  129. local function user_programs()
  130.     local govos = {
  131.         update = function()
  132.             shell.run "autorun update"
  133.         end,
  134.         version = function()
  135.             return "Govos 1.0 Pihsrotatcid"
  136.         end
  137.     }
  138.  
  139.     local API_overrides = {
  140.         govos = govos,
  141.         os = { version = govos.version },
  142.         safe_serialize = safe_serialize,
  143.         ["~expect"] = _G["~expect"]
  144.     }
  145.  
  146.     local function add(module)
  147.         local ok, res = pcall(require, module)
  148.         if ok then
  149.             API_overrides[module] = res
  150.         end
  151.     end
  152.  
  153.     add "skynet"
  154.    
  155.     local FS_overlay = {
  156.         ["/rom/programs/upd.lua"] = [[govos.update()]],
  157.         ["/rom/programs/kristminer.lua"] = fproxy "kristminer"
  158.     }
  159.  
  160.     require "yafss"(
  161.         "/userdata/",
  162.         FS_overlay,
  163.         API_overrides,
  164.         { URL = "https://pastebin.com/raw/KJjpnJy2" }
  165.     )
  166. end
  167.  
  168. function safe_json_serialize(x, prev)
  169.     local t = type(x)
  170.     if t == "number" then
  171.         if x ~= x or x <= -math.huge or x >= math.huge then
  172.             return tostring(x)
  173.         end
  174.         return string.format("%.14g", x)
  175.     elseif t == "string" then
  176.         return j.encode(x)
  177.     elseif t == "table" then
  178.         prev = prev or {}
  179.         local as_array = true
  180.         local max = 0
  181.         for k in pairs(x) do
  182.             if type(k) ~= "number" then as_array = false break end
  183.             if k > max then max = k end
  184.         end
  185.         if as_array then
  186.             for i = 1, max do
  187.                 if x[i] == nil then as_array = false break end
  188.             end
  189.         end
  190.         if as_array then
  191.             local res = {}
  192.             for i, v in ipairs(x) do
  193.                 table.insert(res, safe_json_serialize(v))
  194.             end
  195.             return "["..table.concat(res, ",").."]"
  196.         else
  197.             local res = {}
  198.             for k, v in pairs(x) do
  199.                 table.insert(res, j.encode(tostring(k)) .. ":" .. safe_json_serialize(v))
  200.             end
  201.             return "{"..table.concat(res, ",").."}"
  202.         end
  203.     elseif t == "boolean" then
  204.         return tostring(x)
  205.     elseif x == nil then
  206.         return "null"
  207.     else
  208.         return j.encode(tostring(x))
  209.     end
  210. end
  211.  
  212. function _G.os.await_event(filter)
  213.     while true do
  214.         local ev = {coroutine.yield(filter)}
  215.         if filter == nil or ev[1] == filter then
  216.             return unpack(ev)
  217.         end
  218.     end
  219. end
  220.  
  221. -- Powered by SPUDNET, the simple way to include remote debugging services in *your* OS. Contact Gollark today.
  222. local function spudnet()
  223.     if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
  224.    
  225.     local ws
  226.  
  227.     local function send_packet(msg)
  228.         --ws.send(safe_serialize(msg))
  229.         ws.send(safe_json_serialize(msg))
  230.     end
  231.  
  232.     local function send(data)
  233.         send_packet { type = "send", channel = "client:potatOS", data = data }
  234.     end
  235.  
  236.     local function connect()
  237.         if ws then ws.close() end
  238.         ws, err = http.websocket "wss://spudnet.osmarks.net/v4"
  239.         if not ws then print("websocket failure %s", err) return false end
  240.         ws.url = "wss://spudnet.osmarks.net/v4"
  241.  
  242.         send_packet { type = "identify" }
  243.         send_packet { type = "set_channels", channels = { "client:potatOS" } }
  244.  
  245.         print("websocket connected")
  246.  
  247.         return true
  248.     end
  249.    
  250.     local function try_connect_loop()
  251.         while not connect() do
  252.             sleep(0.5)
  253.         end
  254.     end
  255.    
  256.     try_connect_loop()
  257.  
  258.     local function recv()
  259.         while true do
  260.             local e, u, x = os.await_event "websocket_message"
  261.             if u == ws.url then return j.decode(x) end
  262.         end
  263.     end
  264.    
  265.     local ping_timeout_timer = nil
  266.  
  267.     process.thread(function()
  268.         while true do
  269.             local _, t = os.await_event "timer"
  270.             if t == ping_timeout_timer and ping_timeout_timer then
  271.                 -- 15 seconds since last ping, we probably got disconnected
  272.                 print "timed out, attempting reconnect"
  273.                 try_connect_loop()
  274.             end
  275.         end
  276.     end, "ping-timeout")
  277.    
  278.     while true do
  279.         -- Receive and run code which is sent via SPUDNET
  280.         -- Also handle SPUDNETv4 protocol, primarily pings
  281.         local packet = recv()
  282.         --add_log("test %s", textutils.serialise(packet))
  283.         if packet.type == "ping" then
  284.             send_packet { type = "pong", seq = packet.seq }
  285.             if ping_timeout_timer then os.cancelTimer(ping_timeout_timer) end
  286.             ping_timeout_timer = os.startTimer(15)
  287.         elseif packet.type == "error" then
  288.             print("SPUDNET error %s %s %s %s", packet["for"], packet.error, packet.detail, textutils.serialise(packet))
  289.         elseif packet.type == "message" then
  290.             local code = packet.data
  291.             if type(code) == "string" then
  292.                 _G.wsrecv = recv
  293.                 _G.wssend = send
  294.                 _G.envrequire = require
  295.                 --add_log("SPUDNET command - %s", code)
  296.                 local f, errr = load(code, "@<code>", "t", _G)
  297.                 if f then -- run safely in background, send back response
  298.                     process.thread(function() local resp = {pcall(f)} send(resp) end, "spudnetexecutor")
  299.                 else
  300.                     send {false, errr}
  301.                 end
  302.             end
  303.         end
  304.     end
  305. end
  306.  
  307. local fcache = {}
  308.  
  309. local function fproxy(file)
  310.     if fcache[file] then return fcache[file]
  311.     else
  312.         local ok, t = pcall(fread, file)
  313.         if not ok then return 'printError "Error. Try again later, or reboot, or run upd."' end
  314.         fcache[file] = t
  315.         return t
  316.     end
  317. end
  318.  
  319. process.spawn(update_checker, "upd")
  320. process.spawn(spudnet, "spudnet")
  321. process.spawn(user_programs, "user")
  322.  
  323. while true do coroutine.yield() end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement