osmarks

PotatOS OmniDisk

Jun 8th, 2019 (edited)
459
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.46 KB | None | 0 0
  1. --[[
  2. PotatOS OmniDisk
  3. A new system to unify the existing PotatOS Uninstall/Debug/Update disks currently in existence.
  4. Comes with a flexible, modular design, centralized licensing, possibly neater code, and a menu.
  5.  
  6. This is designed to be executed by the OmniDisk Loader (https://pastebin.com/S1RS76pv) but may run on its own, though this is NOT a supported configuration.
  7.  
  8. This is NOT usable simply by copying it onto a disk due to PotatOS signing requirements.
  9. You must use the dcopy (https://pastebin.com/TfNgRUKC) program or manually generate a hex-format ECC signature and write it to "disk/signature" (PotatOS will, however, not run it unless this signature is from the PDSK).
  10. ]]
  11.  
  12. local function try_report_incident(...)
  13.     if _G.report_incident then
  14.         _G.report_incident(...)
  15.         print "This incident has been reported."
  16.     end
  17. end
  18.  
  19. local r = process.get_running()
  20. local sandbox = process.info "sandbox"
  21. if sandbox then
  22.     for _, p in pairs(process.list()) do
  23.         if p.parent == sandbox and p.ID ~= r.ID then
  24.             process.signal(p.ID, process.signals.KILL)
  25.         end
  26.     end
  27. end
  28. pcall(process.signal, "sandbox", process.signals.KILL)
  29. os.queueEvent "stop"
  30.  
  31. local function fetch(URL)
  32.     local h, e = http.get(URL)
  33.     if not h then error(e) end
  34.     local o = h.readAll()
  35.     h.close()
  36.     return o
  37. end
  38.  
  39. local UUID = "@UUID@" -- Populated by dcopy utility, in some setups
  40.  
  41. local args = ...
  42.  
  43. if type(args) == "table" and args.UUID then UUID = args.UUID end
  44.  
  45. local json
  46. if _G.json_for_disks_and_such then json = _G.json_for_disks_and_such
  47. elseif textutils.unserialiseJSON then
  48.     json = { encode = textutils.serialiseJSON, decode = textutils.unserialiseJSON }
  49. else error "No JSON library exists, somehow" end
  50. local license_data = fetch "https://pastebin.com/raw/viz0spjb"
  51. local licenses = json.decode(license_data)
  52. local license = licenses[UUID]
  53.  
  54. local disk_ID
  55. local disk_loader_args = args.arguments
  56. if type(disk_loader_args) == "table" and disk_loader_args.ID then
  57.     disk_ID = disk_loader_args.ID
  58. end
  59.  
  60. local function runfile(program, ...)
  61.     local ok, err = loadfile(program)
  62.     if not ok then error(err) end
  63.     ok(...)
  64. end
  65.  
  66. local features = {
  67.     test = {
  68.         fn = function() print "Hello, World!" end,
  69.         description = "Test function."
  70.     },
  71.     exit = {
  72.         fn = function() os.reboot() end,
  73.         description = "Leave OmniDisk, return to PotatOS.",
  74.         always_permitted = true
  75.     },
  76.     UUID = {
  77.         fn = function() print("UUID:", UUID) print("Disk ID:", disk_ID or "[???]") end,
  78.         description = "Print this OmniDisk's Licensing UUID.",
  79.         always_permitted = true
  80.     },
  81.     uninstall = {
  82.         fn = function() print "Uninstalling..." _G.uninstall "omnidisk" end,
  83.         description = "Uninstall potatOS"
  84.     },
  85.     REPL = {
  86.         fn = function() runfile("/rom/programs/shell.lua", "lua") end,
  87.         description = "Open a Lua REPL for debugging."
  88.     },
  89.     shell = {
  90.         fn = function()
  91.             printError "WARNING!"
  92.             print "Do not attempt to modify the code of this PotatOS OmniDisk. Unauthorized attempts to do so will invalidate the signature and make the disk unusable. All code beyond a limited core is stored in an online file to which you do not have write access. Probably. Contact gollark for further information."
  93.             runfile "/rom/programs/shell.lua"
  94.         end,
  95.         description = "Open an unsandboxed shell."
  96.     },
  97.     update = {
  98.         fn = function() runfile("autorun", "update") end,
  99.         description = "Update PotatOS."
  100.     },
  101.     dump_license = {
  102.         fn = function() print(UUID) textutils.pagedPrint(textutils.serialise(license)) end,
  103.         description = "Dump license information."
  104.     },
  105.     primes = {
  106.         fn = function()
  107.             if not _G.findprime or not _G.isprime then
  108.                 error "findprime/isprime not available. Update potatOS."
  109.             end
  110.             write "Difficulty? (1-16) "
  111.             local difficulty = tonumber(read())
  112.             if type(difficulty) ~= "number" then error "ERR_PEBKAC\nThat's not a number." end
  113.             local maxrand = math.pow(10, difficulty)
  114.             local p1 = findprime(math.random(2, maxrand))
  115.             local p2 = findprime(math.random(2, maxrand))
  116.            
  117.             local num = p1 * p2
  118.             print("Please find the prime factors of the following number:", num)
  119.             write "Factor 1: "
  120.             local f1 = tonumber(read())
  121.             write "Factor 2: "
  122.             local f2 = tonumber(read())
  123.             if (f1 == p1 and f2 == p2) or (f2 == p1 and f1 == p2) then
  124.                 print "Yay! You got it right!"
  125.             else
  126.                 print("Factors", f1, f2, "invalid.", p1, p2, "expected.")
  127.             end
  128.         end,
  129.         description = "Bored? You can factor some semiprimes!"
  130.     },
  131.     potatoplex = {
  132.         fn = function()
  133.             write "Run potatoplex with arguments: "
  134.             local args = read()
  135.             runfile("rom/programs/http/pastebin.lua", "run", "wYBZjQhN", args)
  136.         end,
  137.         description = "Potatoplex your life!"
  138.     },
  139.     chronometer = {
  140.         fn = function()
  141.             runfile("rom/programs/http/pastebin.lua", "run", "r24VMWk4")
  142.         end,
  143.         description = "Tell the time with Chronometer!"
  144.     },
  145.     latest_paste = {
  146.         fn = function()
  147.             write "WARNING: This views the latest paste on Pastebin. Exposure to the raw output of the Internet may be detrimental to your mental health. Do you want to continue (y/n)? "
  148.             local yn = read()
  149.             if not yn:lower():match "y" then return end
  150.             local html = fetch "https://pastebin.com/LW9RFpmY"
  151.             local id = html:match [[<ul class="right_menu"><li><a href="/([A-Za-z0-9]+)">]]
  152.             local url = ("https://pastebin.com/raw/%s"):format(id)
  153.             local title = html:match [[<ul class="right_menu"><li><a href="/[A-Za-z0-9]+">([^<]+)</a>]]
  154.             local content = fetch(url)
  155.             term.clear()
  156.             term.setCursorPos(1, 1)
  157.             textutils.pagedPrint(title .. "\n" .. url .. "\n\n" .. content)
  158.         end,
  159.         description = "View latest paste on Pastebin."
  160.     }
  161. }
  162.  
  163. local function wait()
  164.     write "Press Any key to continue."
  165.     os.pullEvent "key"
  166.     local timer = os.startTimer(0)
  167.     while true do
  168.         local e, arg = os.pullEvent()
  169.         if (e == "timer" and arg == timer) or e == "char" then return end
  170.     end
  171. end
  172.  
  173. if not license then
  174.     printError(([[ERR_NO_LICENSE
  175. This disk (UUID %s) does not have an attached license and is invalid.
  176. This should not actually happen, unless you have meddled with the disk while somehow keeping the signature intact.
  177. Please contact gollark.]]):format(tostring(UUID)))
  178.     try_report_incident(("OmniDisk UUID %s has no license data"):format(tostring(UUID)), {"security", "omnidisk"}, {
  179.         extra_meta = {
  180.             disk_ID = disk_ID,
  181.             omnidisk_UUID = UUID
  182.         }
  183.     })
  184.     wait()
  185.     os.reboot()
  186. end
  187.  
  188. if disk_ID then
  189.     local license_ID = license.disk
  190.     local ok = false
  191.     if type(license_ID) == "table" then
  192.         for _, id in pairs(license_ID) do
  193.             if id == disk_ID then ok = true break end
  194.         end
  195.     elseif type(license_ID) == "number" then
  196.         if license_ID == disk_ID then ok = true end
  197.     else
  198.         ok = true
  199.     end
  200.     if not ok then
  201.         printError(([[ERR_WRONG_DISK
  202. This disk (ID %d) is not (one of) the disk(s) specified in your licensing information.
  203. This license (UUID %s) allows use of this/these disk(s): %s.
  204. If you believe this to be in error, please contact gollark so this can be corrected.
  205. Otherwise, stop cloning disks, or contact gollark to have unique UUIDs issued to each.]]):format(disk_ID, UUID, json.encode(license_ID)))
  206.         try_report_incident(("Disk ID mismatch: %d used with license %s"):format(disk_ID, UUID, json.encode(license_ID)), {"security", "omnidisk"}, {
  207.             extra_meta = {
  208.                 permitted_disk_IDs = license_ID,
  209.                 disk_ID = disk_ID,
  210.                 omnidisk_UUID = UUID
  211.             }
  212.         })
  213.         wait()
  214.         os.reboot()
  215.     end
  216. end
  217.  
  218. local permitted_feature_lookup = {}
  219. for _, feature in pairs(license.features) do
  220.     permitted_feature_lookup[feature] = true
  221. end
  222.  
  223. while true do
  224.     term.setCursorPos(1, 1)
  225.     term.clear()
  226.  
  227.     local usable = {}
  228.     local i = 0
  229.  
  230.     print [[Welcome to PotatOS OmniDisk!
  231. Available options:]]
  232.  
  233.     for name, feature in pairs(features) do
  234.         if permitted_feature_lookup["*"] or permitted_feature_lookup[name] or feature.always_permitted then
  235.             textutils.pagedPrint(("%d. %s - %s"):format(i, name, feature.description or "[no description available]"))
  236.             usable[i] = feature.fn
  237.             usable[name] = feature.fn
  238.             i = i + 1
  239.         end
  240.     end
  241.  
  242.     write "Select an option: "
  243.     local option = read()
  244.     local fn
  245.     local as_num = tonumber(option)
  246.  
  247.     if as_num then fn = usable[as_num] else fn = usable[option] end
  248.     if not fn then
  249.         printError(("ERR_ID_10T\nPlease select an option which actually exists.\n'%s' doesn't."):format(tostring(option)))
  250.         wait()
  251.     else
  252.         local ok, res = pcall(fn)
  253.         if not ok then
  254.             printError(res)
  255.             wait()
  256.         else
  257.             wait()
  258.         end
  259.     end
  260. end
Add Comment
Please, Sign In to add comment