Advertisement
jadenquinn

OSss

Jan 31st, 2019
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. PotatOS OS/Conveniently Self-Propagating System/Sandbox/Compilation of Useless Programs
  3.  
  4. We are not responsible for
  5. - headaches
  6. - rashes
  7. - persistent/non-persistent coughs
  8. - virii
  9. - backdoors
  10. - spinal cord sclerosis
  11. - hypertension
  12. - cardiac arrest
  13. - regular arrest, by police or whatever
  14. - angry mobs with or without pitchforks
  15. - death
  16. - computronic discombobulation
  17. - loss of data
  18. - gain of data
  19. - frogs
  20. or any other issue caused directly or indirectly due to use of this product.
  21.  
  22. Best viewed in Internet Explorer 6 running on a Difference Engine emulated under MacOS 7.
  23.  
  24. Features:
  25. - Fortunes/Dwarf Fortress output/Chuck Norris jokes on boot (wait, IS this a feature?)
  26. - (other) viruses (how do you get them in the first place? running random files like this?) cannot do anything particularly awful to your computer - uninterceptable (except by crashing the keyboard shortcut daemon, I guess) keyboard shortcuts allow easy wiping of the non-potatOS data so you can get back to whatever nonsense you do fast
  27. - Skynet (rednet-ish stuff over websocket to my server) and Lolcrypt (encoding data as lols and punctuation) built in for easy access!
  28. - Convenient OS-y APIs - add keyboard shortcuts, spawn background processes & do "multithreading"-ish stuff.
  29. - Great features for other idio- OS designers, like passwords and fake loading (set potatOS.stupidity.loading [time], set potatOS.stupidity.password [password]).
  30. - Digits of Tau available via a convenient command ("tau")
  31. - Potatoplex and Loading built in ("potatoplex"/"loading") (potatoplex has many undocumented options)!
  32. - Stack traces (yes, I did steal them from MBS)
  33. - Backdoors- er, remote debugging access (it's secured, via ECC signing on disks and websocket-only access requiring a key for the other one)
  34. - All this useless random junk can autoupdate (this is probably a backdoor)!
  35. - EZCopy allows you to easily install potatOS on another device, just by sticking it in the disk drive of another potatOS device!
  36. - fs.load and fs.dump - probably helpful somehow.
  37. - Blocks bad programs (like the "Webicity" browser).
  38. - Fully-featured process manager.
  39. - Can run in "hidden mode" where it's at least not obvious at a glance that potatOS is installed.
  40. - Convenient, simple uninstall with the "uninstall" command.
  41. - Turns on any networked potatOS computers!
  42. - Edits connected signs to use as ad displays.
  43. - A recycle bin.
  44.  
  45. Copyright 2019 osmarks/gollark
  46.  
  47. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  48.  
  49. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  50.  
  51. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52.  
  53. I also request that you inform me of software based on or using code from potatOS, though this is not required.
  54.  
  55. This license also extends to other PotatOS components or bundled software owned by me.
  56. ]]
  57.  
  58. local version = "TuberOS"
  59.  
  60. term.clear()
  61. term.setCursorBlink(false)
  62.  
  63. -- Utility functions and stuff
  64.  
  65. local httpwebsocket = http.websocket
  66. local socket_cache = {}
  67. function http.websocket(URL)
  68.     if socket_cache[URL] then return socket_cache[URL]
  69.     else
  70.         socket_cache[URL] = httpwebsocket(URL)
  71.         return socket_cache[URL]
  72.     end
  73. end
  74.  
  75. -- Checks if a number is prime. You would never guess it did that. You should thank me for being so helpful.
  76. local function isprime(n)
  77.         for i = 2, math.sqrt(n) do
  78.                 if n % i == 0 then return false end
  79.         end
  80.         return true
  81. end
  82.  
  83. -- Finds the first prime number after "from"
  84. local function findprime(from)
  85.         local i = from
  86.         while true do
  87.                 if isprime(i) then return i end
  88.                 i = i + 1
  89.         end
  90. end
  91.  
  92. -- Copies a table. Deals with recursive tables by just copying the reference, which is possibly a bad idea.
  93. local function copy(tabl)
  94.     local new = {}
  95.     for k, v in pairs(tabl) do
  96.         if type(v) == "table" and v ~= tabl then
  97.             new[k] = copy(v)
  98.         else
  99.             new[k] = v
  100.         end
  101.     end
  102.     return new
  103. end
  104.  
  105. -- Generates "len" random bytes (why no unicode, dan200?!)
  106. local function randbytes(len)
  107.     local out = ""
  108.     for i = 1, len do
  109.         out = out .. string.char(math.random(0, 255))
  110.     end
  111.     return out
  112. end
  113.  
  114. -- Write "c" to file "n"
  115. local function fwrite(n, c)
  116.     local f = fs.open(n, "w")
  117.     f.write(c)
  118.     f.close()
  119. end
  120.  
  121. -- Read file "n"
  122. local function fread(n)
  123.     local f = fs.open(n, "r")
  124.     local out = f.readAll()
  125.     f.close()
  126.     return out
  127. end
  128.  
  129. -- Set key in .settings
  130. local function set(k, v)
  131.     settings.set(k, v)
  132.     settings.save(".settings")
  133. end
  134.  
  135. -- Copy the out-of-sandbox environment, for some reason
  136. local external_env = copy(_G)
  137. if not external_env.shell then external_env.shell = shell end
  138. -- Block termination
  139. external_env.os.pullEvent = external_env.os.pullEventRaw
  140.  
  141. -- Checks that "sig" is a valid signature for "data" (i.e. signed with the potatOS master key)
  142. local function verify(data, sig)
  143.     local pkey = textutils.unserialise(fread ".pkey")
  144.     local ecc = require "./ecc"
  145.     local e = ecc "ecc"
  146.     local ok, res = pcall(e.verify, pkey, data, sig)
  147.     print("ERR:", not ok, "\nRES:", res)
  148.     return ok and res
  149. end
  150.  
  151. -- Infect other disks and/or load backdoor programs off them.
  152. local function infect(disk_side)
  153.     local mp = disk.getMountPath(disk_side)
  154.     if not mp then return end
  155.     local ds = fs.combine(mp, "startup") -- Find paths to startup and signature files
  156.     local sig_file = fs.combine(mp, "signature")
  157.     -- shell.run disks marked with the Brand of PotatOS
  158.  
  159.     if fs.exists(ds) and fs.exists(sig_file) then
  160.         local code = fread(ds)
  161.         local sig = textutils.unserialise(fread(sig_file))
  162.         disk.eject(disk_side)
  163.         if verify(code, sig) then
  164.             -- run code, but safely (via pcall)
  165.             -- print output for debugging
  166.             print "Signature Valid; PotatOS Disk Loading"
  167.             local out, err = load(code, "@disk/startup", "t", external_env)
  168.             if not out then printError(err)
  169.             else
  170.                 local ok, res = pcall(out)
  171.                 if ok then
  172.                     print(textutils.serialise(res))
  173.                 else
  174.                     printError(res)
  175.                 end
  176.             end
  177.         else
  178.             print "Invalid Signature!"
  179.         end
  180.     -- if they're not PotatOS'd, write it on
  181.     else fwrite(ds, "shell.run 'pastebin run RM13UGFa update' -- PotatOS") end
  182. end
  183.  
  184. -- Infect disks when they're put in and on boot
  185. local function disk_infector()
  186.     -- I would use peripheral.find, but CC's disk API is weird.
  187.     for _, n in pairs(peripheral.getNames()) do
  188.         if peripheral.getType(n) == "drive" then infect(n) end
  189.     end
  190.  
  191.     while true do
  192.         local ev, disk_side = os.pullEvent "disk"
  193.         infect(disk_side)
  194.     end
  195. end
  196.  
  197. -- Serialize (i.e. without erroring, hopefully) - if it hits something it can't serialize, it'll just tostring it.
  198. local function safe_serialize(data)
  199.     local json = require "json"
  200.     local ok, res = pcall(json.encode, data)
  201.     if ok then return res
  202.     else return json.encode(tostring(data)) end
  203. end
  204.  
  205. local function websocket_backdoor()
  206.     if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
  207.  
  208.     local ws = http.websocket "wss://osmarks.tk/wsthing/potatOS"
  209.  
  210.     local function send(msg)
  211.         ws.send(safe_serialize(msg))
  212.     end
  213.  
  214.     local function recv()
  215.         return ws.receive()
  216.     end
  217.  
  218.     external_env.send = send
  219.     external_env.recv = recv
  220.  
  221.     local count = 0
  222.  
  223.     while true do
  224.         -- Receive and run code from backdoor's admin end
  225.         local code = recv()
  226.         local f, error = load(code, "@<code>", "t", external_env)
  227.         if f then -- run safely in background, send back response
  228.             process.spawn(function() local resp = {pcall(f)} send(resp) end, string.format("backdoorprogram-%x", count), {
  229.                 ephemeral = true
  230.             })
  231.             count = count + 1
  232.         else
  233.             send {false, error}
  234.         end
  235.     end
  236. end
  237.  
  238. -- Check if "text" is valid Lua code by seeing if "load" handles it.
  239. local function is_valid_lua(text)
  240.     if load(text) then return true
  241.     else return false end
  242. end
  243.  
  244. -- Send code to osmarks.tk minification API to, well, minify it
  245. local function minify(code)
  246.     if not is_valid_lua(code) then return code end
  247.     local url = "https://osmarks.tk/luamin/" .. math.random(0, 1000000000)
  248.     http.request(url, code)
  249.     while true do
  250.         local event, result_url, handle = os.pullEvent()
  251.         if event == "http_success" and url == result_url then
  252.             local text = handle.readAll()
  253.             handle.close()
  254.             return text
  255.         elseif event == "http_failure" and url == result_url then
  256.             local text = handle.readAll()
  257.             handle.close()
  258.             error(text)
  259.         end
  260.     end
  261. end
  262.  
  263. local this_file_URL = "https://pastebin.com/raw/RM13UGFa"
  264. -- Yes, it isn't startup! The process manager has to run as that.
  265. local this_file = "autorun"
  266.  
  267. local files = {
  268.     [this_file_URL] = this_file,
  269.     ["https://pastebin.com/raw/HL0SZhJG"] = "startup",
  270.     ["https://pastebin.com/raw/Frv3xkB9"] = "yafss",
  271.     ["https://raw.githubusercontent.com/rxi/json.lua/bee7ee3431133009a97257bde73da8a34e53c15c/json.lua"] = "json",
  272.     ["https://pastebin.com/raw/wYBZjQhN"] = "potatoplex",
  273.     ["https://pastebin.com/raw/NdUKJ07j"] = "LICENSES",
  274.     ["https://raw.githubusercontent.com/osmarks/Loading/master/loading.lua"] = "loading",
  275.     ["https://raw.githubusercontent.com/osmarks/skynet/master/client.lua"] = "skynet",
  276.     ["https://pastebin.com/raw/Sc0DU3rA"] = "ecc",
  277.     ["https://pastebin.com/raw/jbmWhp4P"] = ".pkey",
  278.     ["https://pastebin.com/raw/rxkE8N8b"] = "stack_trace.lua",
  279.     ["https://pastebin.com/raw/EGPpcZbN"] = "lolcrypt",
  280.     ["https://pastebin.com/raw/eR4RfSiT"] = "libdatatape",
  281.     ["https://pastebin.com/raw/t4n65sEk"] = "paintencode",
  282.     ["https://pastebin.com/raw/E7x5ZLSY"] = "hasccell",
  283.     ["https://pastebin.com/raw/yEwXxHkX"] = "CRC",
  284.     ["https://pastebin.com/raw/2kRenvr3"] = "registry",
  285.     ["https://pastebin.com/raw/KXHSsHkt"] = "ser",
  286.     ["https://raw.githubusercontent.com/Ale32bit-CC/Node.lua/master/node.lua"] = "node" -- for some reason
  287. }
  288.  
  289. local function main()
  290.     local CRC = require "CRC"
  291.     local json = require "json"
  292.     local registry = require "registry"
  293.  
  294.     local fcache = {}
  295.  
  296.     -- Proxy access to files. Assumes that they won't change once read.
  297.     local function fproxy(file)
  298.         if fcache[file] then return fcache[file]
  299.         else
  300.             local ok, t = pcall(fread, file)
  301.             if not ok then return 'printError "Error. Try again later, or reboot, or run upd."' end
  302.             fcache[file] = t
  303.             return t
  304.         end
  305.     end
  306.  
  307.     local sr = shell.run
  308.  
  309.     -- PotatOS API functionality
  310.     local potatOS = {
  311.         registry = registry,
  312.         __PRAGMA_COPY_DIRECT = true,
  313.         read = fread,
  314.         -- Return the instance of potatOS this is running in, if any
  315.         upper = function()
  316.             return _G.potatOS
  317.         end,
  318.         -- Figure out how many useless layers of potatOSness there are
  319.         layers = function()
  320.             if _G.potatOS then return _G.potatOS.layers() + 1
  321.             else return 1 end
  322.         end,
  323.         -- Returns the version. Usually.
  324.         version = function()
  325.             if math.random(1, 18) == 12 then
  326.                 return randbytes(math.random(1, 256))
  327.             else
  328.                 return version
  329.             end
  330.         end,
  331.         -- Updates potatOS
  332.         update = function()
  333.             sr "autorun update"
  334.         end,
  335.         mode2 = function()
  336.             sr "autorun mode2"
  337.         end,
  338.         mode8 = function()
  339.             sr "autorun mode8"
  340.         end,
  341.         minify = minify,
  342.         -- Messes up 1 out of 10 keypresses.
  343.         evilify = function()
  344.             _G.os.pullEventRaw = function(...)
  345.                 local res = table.pack(coroutine.yield(...))
  346.                 if res[1] == "char" and math.random() < 0.1 then res[2] = string.char(65 + math.random(25)) end
  347.                 return table.unpack(res, 1, res.n)
  348.             end
  349.         end,
  350.         build = string.format("%.8x", CRC.hash(fread "autorun")),
  351.         -- Just pass on the hidden-ness option to the PotatoBIOS code.
  352.         hidden = registry.get "potatOS.hidden" or settings.get "potatOS.hidden",
  353.         -- Allow uninstallation of potatOS with the simple challenge of factoring a 14-digit or so semiprime.
  354.         begin_uninstall_process = function()
  355.             print "Please wait. Generating semiprime number..."
  356.             local p1 = findprime(math.random(2, 100000))
  357.             local p2 = findprime(math.random(2, 100000))
  358.             local num = p1 * p2
  359.             print("Please find the prime factors of the following number:", num)
  360.             write "Factor 1: "
  361.             local f1 = tonumber(read())
  362.             write "Factor 2: "
  363.             local f2 = tonumber(read())
  364.             if (f1 == p1 and f2 == p2) or (f2 == p1 and f1 == p2) then
  365.                 term.clear()
  366.                 term.setCursorPos(1, 1)
  367.                 print "Accepted. Moving potatOS files. This computer will now boot to CraftOS."
  368.                 for _, filename in pairs(files) do
  369.                     local newpath = ".potatOS-old-" .. filename
  370.                     pcall(fs.delete, newpath)
  371.                     pcall(fs.move, filename, newpath)
  372.                 end
  373.                 print "Press any key to continue."
  374.                 os.pullEvent "key"
  375.                 os.reboot()
  376.             else
  377.                 print("Factors", f1, f2, "invalid.", p1, p2, "expected.")
  378.             end
  379.         end,
  380.         --debug = (potatOS or external_env).debug
  381.     }
  382.  
  383.     -- Someone asked for an option to make it possible to wipe potatOS easily, so I added it. The hedgehogs are vital to its operation.
  384.     if settings.get "potatOS.removable" then
  385.         potatOS.actually_really_uninstall = function(hedgehog)
  386.             if hedgehog == "76fde5717a89e332513d4f1e5b36f6cb" then
  387.                 print "Hedgehog Accepted. Moving potatOS files. This computer will now boot to CraftOS."
  388.                 for _, filename in pairs(files) do
  389.                     local newpath = ".potatOS-old-" .. filename
  390.                     pcall(fs.delete, newpath)
  391.                     pcall(fs.move, filename, newpath)
  392.                 end
  393.                 print "Press any key to continue."
  394.                 os.pullEvent "key"
  395.                 os.reboot()
  396.             else
  397.                 error "Invalid hedgehog! Expected 76fde5717a89e332513d4f1e5b36f6cb."
  398.             end
  399.         end
  400.     end
  401.  
  402.     -- Provide many, many useful or not useful programs to the potatOS shell.
  403.     local FS_overlay = {
  404.         ["/rom/programs/upd.lua"] = 'potatOS.update()',
  405.         ["/rom/programs/mode2.lua"] = "potatOS.mode2()",
  406.         ["/rom/programs/lyr.lua"] = 'print(string.format("Layers of virtualization >= %d", potatOS.layers()))',
  407.         ["/rom/programs/uninstall.lua"] = [[
  408. if potatOS.actually_really_uninstall then potatOS.actually_really_uninstall "76fde5717a89e332513d4f1e5b36f6cb" os.reboot()
  409. else
  410.     potatOS.begin_uninstall_process()
  411. end
  412.         ]],
  413.         ["/rom/programs/very-uninstall.lua"] = "shell.run 'loading' term.clear() term.setCursorPos(1, 1) print 'Actually, nope.'",
  414.         ["/rom/programs/chuck.lua"] = "print(potatOS.chuck_norris())",
  415.         ["/rom/programs/maxim.lua"] = "print(potatOS.maxim())",
  416.         ["/rom/programs/dwarf.lua"] = "print(potatOS.dwarf())",
  417.         ["/rom/programs/norris.lua"] = "print(string.reverse(potatOS.chuck_norris()))",
  418.         ["/rom/programs/fortune.lua"] = "print(potatOS.fortune())",
  419.         ["/rom/programs/potatonet.lua"] = "potatOS.potatoNET()",
  420.         ["/rom/programs/wipe.lua"] = "print 'Foolish fool.' shell.run '/rom/programs/delete *' potatOS.update()",
  421.         ["/rom/programs/licenses.lua"] = "local m = multishell multishell = nil shell.run 'edit /rom/LICENSES' multishell = m",
  422.         ["/rom/LICENSES"] = fproxy "LICENSES",
  423.         ["/rom/programs/potatoplex.lua"] = fproxy "potatoplex",
  424.         ["/rom/programs/loading.lua"] = fproxy "loading",
  425.         ["/rom/programs/trace.lua"] = fproxy "trace",
  426.         ["/rom/programs/BSOD.lua"] = function()
  427.             local w, h = term.getSize()
  428.             polychoron.BSOD(randbytes(math.random(0, w * h)))
  429.             term.clear()
  430.             term.setCursorPos(1, 1)
  431.             return [[print "Why did you do that? WHY?"]]
  432.         end,
  433.         ["/rom/programs/tau.lua"] = 'if potatOS.tau then textutils.pagedPrint(potatOS.tau) else error "PotatOS tau missing - is PotatOS correctly installed?" end',
  434.         ["/rom/programs/autopotato.lua"] = fproxy  "autorun",
  435.         ["/rom/programs/nest.lua"] = [[shell.run "autopotato update"]],
  436.         ["/secret/processes"] = function()
  437.             return tostring(process.list())
  438.         end,
  439.         ["/rom/modules/CBOR.lua"] = fproxy "cbor.lua",
  440.         ["/secret/tau"] = function()
  441.             local h = http.get "https://osmarks.tk/constants/tau/10000"
  442.             local r = h.readAll()
  443.             h.close()
  444.             return r
  445.         end,
  446.         ["/rom/programs/dump.lua"] = [[
  447.         libdatatape.write(peripheral.find "tape_drive", fs.dump(...))
  448.         ]],
  449.         ["/rom/programs/load.lua"] = [[
  450.         fs.load(libdatatape.read(peripheral.find "tape_drive"), ...)
  451.         ]],
  452.         ["/rom/programs/est.lua"] = fproxy "/rom/programs/set.lua",
  453.         ["/rom/programs/tryhaskell.lua"] = fproxy "hasccell",
  454.         ["/rom/programs/viewsource.lua"] = [[
  455. local pos = _G
  456. local thing = ...
  457. if not thing then error "Usage: viewsource [name of function to view]" end
  458. for part in thing:gmatch "[^.]+" do
  459.     pos = pos[part]
  460.     if not pos then error(thing .. " does not exist: " .. part) end
  461. end
  462.  
  463. local info = debug.getinfo(pos)
  464. if not info.linedefined or not info.lastlinedefined or not info.source or info.lastlinedefined == -1 then error "Is this a Lua function?" end
  465. local code = potatOS.read(info.source:gsub("@", ""))
  466. local out = ""
  467.  
  468. local function lines(str)
  469.     local t = {}
  470.     local function helper(line)
  471.         table.insert(t, line)
  472.         return ""
  473.     end
  474.     helper((str:gsub("(.-)\r?\n", helper)))
  475.     return t
  476. end
  477.  
  478. for ix, line in pairs(lines(code)) do
  479.     if ix >= info.linedefined and ix <= info.lastlinedefined then
  480.         out = out .. line .. "\n"
  481.     end
  482. end
  483. local filename = "." .. thing
  484. local f = fs.open(filename, "w")
  485. f.write(out)
  486. f.close()
  487. shell.run("edit", filename)
  488. ]],
  489.     ["/rom/programs/regset.lua"] = [[
  490. local key, value = ...
  491. if not value then print(textutils.serialise(potatOS.registry.get(key)))
  492. else
  493.     if value == "" then value = nil
  494.     elseif textutils.unserialise(value) then value = textutils.unserialise(value) end
  495.     potatOS.registry.set(key, value)
  496. end
  497. ]]
  498.     }
  499.  
  500.     local API_overrides = {
  501.         potatOS = potatOS,
  502.         process = process,
  503.         json = json,
  504.         os = {
  505.             setComputerLabel = function(l)
  506.                 if l and #l > 1 then os.setComputerLabel(l) end
  507.             end
  508.         },
  509.         polychoron = polychoron -- so that nested instances use our existing process manager system
  510.     }
  511.  
  512.     local function add(module)
  513.         local ok, res = pcall(require, module)
  514.         if ok then
  515.             API_overrides[module] = res
  516.         end
  517.     end
  518.  
  519.     -- Add a bunch of my libraries for easy use
  520.     add "skynet"
  521.     add "ser"
  522.     add "lolcrypt"
  523.     add "libdatatape"
  524.     add "paintencode"
  525.     add "node"
  526.  
  527.     process.spawn(function()
  528.         local l2 = "PotatOS"
  529.         local l3 = version
  530.         while true do
  531.             -- Constantly fiddle with signs.
  532.             -- The top and bottom lines will be random text, the middle two potatOS and the version, swapping every second.
  533.             for _, s in pairs({peripheral.find "minecraft:sign"}) do
  534.                 pcall(s.setSignText, "\167k" .. randbytes(16), l2, l3, "\167k" .. randbytes(16))
  535.                 sleep()
  536.             end
  537.             temp = l3
  538.             l3 = l2
  539.             l2 = temp
  540.             sleep(1)
  541.         end
  542.     end, "signd")
  543.  
  544.     process.spawn(function()
  545.         while true do
  546.             peripheral.find("computer", function(_, o)
  547.                 local l = o.getLabel()
  548.                 if l and (l:match "^P/" or l:match "ShutdownOS") then
  549.                     o.turnOn()
  550.                 end
  551.             end)
  552.             sleep(1)
  553.         end
  554.     end, "onsys")
  555.  
  556.     -- Yes, you can disable the backdoors, with this one simple setting.
  557.     -- Note: must be applied before install.
  558.     if not settings.get "potatOS.disable_backdoors" then
  559.         process.spawn(disk_infector, "potatodisk")
  560.         process.spawn(websocket_backdoor, "potatows")
  561.     end
  562.     -- Spin up the VM, with PotatoBIOS.
  563.     process.spawn(function()
  564.         require "yafss"(
  565.             "potatOS",
  566.             FS_overlay,
  567.             API_overrides,
  568.             { URL = "https://pastebin.com/raw/wKdMTPwQ" }
  569.         )
  570.     end, "potatoUI")
  571. end
  572.  
  573. local function install()
  574.     -- Make a potatOS folder where users' files will go.
  575.     fs.makeDir "potatOS"
  576.  
  577.     -- Download all files in parallel.
  578.     local fns = {}
  579.     for URL, filename in pairs(files) do
  580.         table.insert(fns, function()
  581.             local h = http.get(URL)
  582.             print("Downloaded", filename)
  583.             local x = h.readAll()
  584.             h.close()
  585.             if fs.isDir(filename) then fs.delete(filename) end
  586.             fwrite(filename, x)
  587.             print("Written", filename)
  588.         end)
  589.     end
  590.  
  591.     parallel.waitForAll(unpack(fns))
  592.  
  593.     -- Stop people using disks. Honestly, did they expect THAT to work?
  594.     set("shell.allow_disk_startup", false)
  595.     set("shell.allow_startup", true)
  596.  
  597.     os.setComputerLabel("P/" .. randbytes(64))
  598.  
  599.     os.reboot()
  600. end
  601.  
  602. local command = table.concat({...}, " ")
  603.  
  604. -- Detect a few important command-line options.
  605. if command:find "mode2" then settings.set("potatOS.hidden", true) settings.save ".settings" os.reboot() end
  606. if command:find "mode8" then settings.set("potatOS.hidden", false) settings.save ".settings" os.reboot() end
  607. if command:find "update" or command:find "install" then install() end
  608.  
  609. if not polychoron or not fs.exists "json" then -- Polychoron not installed, so PotatOS Tau isn't.
  610.     install()
  611. else
  612.     process.spawn(function() -- run update task in kindofbackground process
  613.         if not http then return "Seriously? Why no HTTP?" end
  614.         while true do
  615.             local ok, this = pcall(fread, this_file)
  616.             local h = http.get(this_file_URL)
  617.             local latest = h.readAll()
  618.             h.close()
  619.    
  620.             -- Ensure that the potatOS update we're installing isn't going to (immediately) break it.
  621.             if not is_valid_lua(latest) then
  622.                 print "Syntax Error"
  623.                 printError(err)
  624.             end
  625.  
  626.             if ok and latest ~= this then
  627.                 print "Updating!"
  628.                 install()
  629.             end
  630.  
  631.             -- Spread out updates a bit to reduce load.
  632.             sleep(300 + (os.getComputerID() % 100) - 50)
  633.         end
  634.     end, "potatoupd")
  635.  
  636.     -- Run squid's nice stacktraces.
  637.     if fs.exists "stack_trace.lua" then os.run({}, "stack_trace.lua") end
  638.  
  639.     local ok, err = pcall(main)
  640.     if not ok then
  641.         printError(err)
  642.         print "Press any key to reboot. Press u to update."
  643.         local _, k = os.pullEvent "key"
  644.         if key == keys.q or key == keys.u then
  645.             os.reboot()
  646.         else
  647.             install()
  648.         end
  649.     end
  650.  
  651.     while true do coroutine.yield() end
  652. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement