doublequestionmark

Boot -- a computercraft bootloader

Jan 25th, 2016
606
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --#--
  2. dev = false
  3. defaultPath = nil
  4. WaitTime = 15
  5. ID = nil
  6. profanity = false
  7.  
  8. --==--==--==--==--==--==--==--==--==--
  9. function cp(str) --FBI, its not what you think it is
  10.   local x, y = term.getSize()
  11.   local cx, cy = term.getCursorPos()
  12.   local l = #str
  13.   term.setCursorPos((x/2)-(l/2), cy)
  14.   print(str)
  15. end
  16.  
  17. function halt()
  18.   os.pullEvent("HALT")
  19. end
  20.  
  21. function fuck(err, act)
  22.   term.setCursorPos(1,1)
  23.   term.setBackgroundColor(colors.white)
  24.   term.clear()
  25.   term.setTextColor(colors.black)
  26.   if profanity then cp("Fuck, it broke") else cp("It broke") end
  27.   print("\r\n")
  28.   if err == nil then cp("Thats all I know") end
  29.   if err ~= nil then print(err) end
  30.   if act == "reboot" then os.reboot() else halt() end
  31. end
  32.  
  33. local counter = 0
  34. function LoadCFG()
  35.     if fs.exists(".bcfg") then
  36.         local f = fs.open(".bcfg", 'r')
  37.         local d = f.readAll()
  38.         f.close()
  39.        
  40.         ion = textutils.unserialize(d)
  41.         for k, v in pairs(ion) do
  42.             if dev then print(tostring(k) .. " = " .. tostring(v)) end
  43.             if k == 'SecureBootFile' then
  44.      if SecureBoot == nil then enableSecureBoot(v) end
  45.    else
  46.      ls = loadstring(k .. " = " .. tostring(v))
  47.             setfenv(ls, getfenv())
  48.             ls()
  49.    end             
  50.         end
  51.         if dev then sleep(.5) end
  52.     end
  53. end
  54.  
  55. --sha256 adapted from: http://www.computercraft.info/forums2/index.php?/topic/8169-sha-256-in-pure-lua/
  56. --usage a5(msg)
  57. local a=2^32;local b=a-1;local function c(d)local mt={}local e=setmetatable({},mt)function mt:__index(f)local g=d(f)e[f]=g;return g end;return e end;local function h(e,i)local function j(k,l)local m,o=0,1;while k~=0 and l~=0 do local p,q=k%i,l%i;m=m+e[p][q]*o;k=(k-p)/i;l=(l-q)/i;o=o*i end;m=m+(k+l)*o;return m end;return j end;local function r(e)local s=h(e,2^1)local t=c(function(k)return c(function(l)return s(k,l)end)end)return h(t,2^e.n or 1)end;local u=r({[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0},n=4})local function v(k,l,w,...)local x=nil;if l then k=k%a;l=l%a;x=u(k,l)if w then x=v(x,w,...)end;return x elseif k then return k%a else return 0 end end;local function y(k,l,w,...)local x;if l then k=k%a;l=l%a;x=(k+l-u(k,l))/2;if w then x=bit32_band(x,w,...)end;return x elseif k then return k%a else return b end end;local function z(A)return(-1-A)%a end;local function B(k,C)if C<0 then return lshift(k,-C)end;return math.floor(k%2^32/2^C)end;local function D(A,C)if C>31 or C<-31 then return 0 end;return B(A%a,C)end;local function lshift(k,C)if C<0 then return D(k,-C)end;return k*2^C%2^32 end;local function E(A,C)A=A%a;C=C%32;local F=y(A,2^C-1)return D(A,C)+lshift(F,32-C)end;local f={0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2}local function G(H)return string.gsub(H,".",function(w)return string.format("%02x",string.byte(w))end)end;local function I(J,n)local H=""for K=1,n do local L=J%256;H=string.char(L)..H;J=(J-L)/256 end;return H end;local function M(H,K)local n=0;for K=K,K+3 do n=n*256+string.byte(H,K)end;return n end;local function N(O,P)local Q=64-(P+9)%64;P=I(8*P,8)O=O.."\128"..string.rep("\0",Q)..P;assert(#O%64==0)return O end;local function R(S)S[1]=0x6a09e667;S[2]=0xbb67ae85;S[3]=0x3c6ef372;S[4]=0xa54ff53a;S[5]=0x510e527f;S[6]=0x9b05688c;S[7]=0x1f83d9ab;S[8]=0x5be0cd19;return S end;local function T(O,K,S)local U={}for V=1,16 do U[V]=M(O,K+(V-1)*4)end;for V=17,64 do local g=U[V-15]local W=v(E(g,7),E(g,18),D(g,3))g=U[V-2]U[V]=U[V-16]+W+U[V-7]+v(E(g,17),E(g,19),D(g,10))end;local k,l,w,X,Y,d,Z,_=S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[8]for K=1,64 do local W=v(E(k,2),E(k,13),E(k,22))local a0=v(y(k,l),y(k,w),y(l,w))local a1=W+a0;local a2=v(E(Y,6),E(Y,11),E(Y,25))local a3=v(y(Y,d),y(z(Y),Z))local a4=_+a2+a3+f[K]+U[K]_,Z,d,Y,X,w,l,k=Z,d,Y,X+a4,w,l,k,a4+a1 end;S[1]=y(S[1]+k)S[2]=y(S[2]+l)S[3]=y(S[3]+w)S[4]=y(S[4]+X)S[5]=y(S[5]+Y)S[6]=y(S[6]+d)S[7]=y(S[7]+Z)S[8]=y(S[8]+_)end;local function a5(O)O=N(O,#O)local S=R({})for K=1,#O,64 do T(O,K,S)end;return G(I(S[1],4)..I(S[2],4)..I(S[3],4)..I(S[4],4)..I(S[5],4)..I(S[6],4)..I(S[7],4)..I(S[8],4))end
  58.  
  59. local function generateKey(strin)
  60.   local key = '"' .. tostring(a5(strin)) .. '"'
  61.   return key
  62. end
  63.  
  64. function enableSecureBoot(file)
  65.   local buffer = fs.open(file, 'r')
  66.   local dump = buffer.readAll()
  67.   --print(dump)
  68.   buffer.close()
  69.   print("Generating Key")
  70.   SecureBootKey = generateKey(dump)
  71.   print("Generated Key")
  72.   --Rewriting startup
  73.   print("Rewriting startup")
  74.   buffer = fs.open('startup', 'r')
  75.   dump = buffer.readAll()
  76.   buffer.close()
  77.   fs.delete("startup")
  78.  
  79.   buffer = fs.open('startup', 'w')
  80.   buffer.write("--#-- \n")
  81.   buffer.write('local SecureBoot = \'' .. file .. "' \n")
  82.   buffer.write('local SecureBootKey = ' .. SecureBootKey .. " \n")
  83.   buffer.write(dump)
  84.   buffer.close()    
  85.   print("Rewrote Startup")
  86.   return 200
  87. end
  88.  
  89. function checkSecureBoot(boot)
  90.   local function protect()
  91.     if SecureBootKey == nil then return true end
  92.     local buffer = fs.open(boot, 'r')
  93.     local dump = buffer.readAll()
  94.     buffer.close()
  95.  
  96.     local key = generateKey(dump)
  97.     if key == '"' .. SecureBootKey .. '"' and boot == SecureBoot then return true end
  98.     if key ~= '"' .. SecureBootKey .. '"' then term.setTextColour(colors.red) print("Secure Boot: Key Not Recognized, This is not the key for " .. SecureBoot) term.setTextColour(colors.black) return false end
  99.     if boot ~= SecureBoot then term.setTextColour(colors.red) print("Secure Boot: File not recognized") term.setTextColour(colors.black) return false end
  100.   end    
  101.   o, e = pcall(protect)
  102.   if not o then fuck(e, 'reboot') end
  103.   return e
  104. end
  105.  
  106. --sha256 algorithm adapted from http://www.computercraft.info/forums2/index.php?/topic/8169-sha-256-in-pure-lua/
  107. local a=2^32;local b=a-1;local function c(d)local mt={}local e=setmetatable({},mt)function mt:__index(f)local g=d(f)e[f]=g;return g end;return e end;local function h(e,i)local function j(k,l)local m,o=0,1;while k~=0 and l~=0 do local p,q=k%i,l%i;m=m+e[p][q]*o;k=(k-p)/i;l=(l-q)/i;o=o*i end;m=m+(k+l)*o;return m end;return j end;local function r(e)local s=h(e,2^1)local t=c(function(k)return c(function(l)return s(k,l)end)end)return h(t,2^e.n or 1)end;local u=r({[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0},n=4})local function v(k,l,w,...)local x=nil;if l then k=k%a;l=l%a;x=u(k,l)if w then x=v(x,w,...)end;return x elseif k then return k%a else return 0 end end;local function y(k,l,w,...)local x;if l then k=k%a;l=l%a;x=(k+l-u(k,l))/2;if w then x=bit32_band(x,w,...)end;return x elseif k then return k%a else return b end end;local function z(A)return(-1-A)%a end;local function B(k,C)if C<0 then return lshift(k,-C)end;return math.floor(k%2^32/2^C)end;local function D(A,C)if C>31 or C<-31 then return 0 end;return B(A%a,C)end;local function lshift(k,C)if C<0 then return D(k,-C)end;return k*2^C%2^32 end;local function E(A,C)A=A%a;C=C%32;local F=y(A,2^C-1)return D(A,C)+lshift(F,32-C)end;local f={0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2}local function G(H)return string.gsub(H,".",function(w)return string.format("%02x",string.byte(w))end)end;local function I(J,n)local H=""for K=1,n do local L=J%256;H=string.char(L)..H;J=(J-L)/256 end;return H end;local function M(H,K)local n=0;for K=K,K+3 do n=n*256+string.byte(H,K)end;return n end;local function N(O,P)local Q=64-(P+9)%64;P=I(8*P,8)O=O.."\128"..string.rep("\0",Q)..P;assert(#O%64==0)return O end;local function R(S)S[1]=0x6a09e667;S[2]=0xbb67ae85;S[3]=0x3c6ef372;S[4]=0xa54ff53a;S[5]=0x510e527f;S[6]=0x9b05688c;S[7]=0x1f83d9ab;S[8]=0x5be0cd19;return S end;local function T(O,K,S)local U={}for V=1,16 do U[V]=M(O,K+(V-1)*4)end;for V=17,64 do local g=U[V-15]local W=v(E(g,7),E(g,18),D(g,3))g=U[V-2]U[V]=U[V-16]+W+U[V-7]+v(E(g,17),E(g,19),D(g,10))end;local k,l,w,X,Y,d,Z,_=S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[8]for K=1,64 do local W=v(E(k,2),E(k,13),E(k,22))local a0=v(y(k,l),y(k,w),y(l,w))local a1=W+a0;local a2=v(E(Y,6),E(Y,11),E(Y,25))local a3=v(y(Y,d),y(z(Y),Z))local a4=_+a2+a3+f[K]+U[K]_,Z,d,Y,X,w,l,k=Z,d,Y,X+a4,w,l,k,a4+a1 end;S[1]=y(S[1]+k)S[2]=y(S[2]+l)S[3]=y(S[3]+w)S[4]=y(S[4]+X)S[5]=y(S[5]+Y)S[6]=y(S[6]+d)S[7]=y(S[7]+Z)S[8]=y(S[8]+_)end;local function a5(O)O=N(O,#O)local S=R({})for K=1,#O,64 do T(O,K,S)end;return G(I(S[1],4)..I(S[2],4)..I(S[3],4)..I(S[4],4)..I(S[5],4)..I(S[6],4)..I(S[7],4)..I(S[8],4))end
  108.  
  109. function ViewInsert()
  110.     if fs.exists("/Views") ~= true then fs.makeDir("/Views") end
  111.     if fs.exists("/Views/main.view") ~= true then
  112.         local f = fs.open("/Views/main.view", 'w')
  113.         local payload = [[{
  114.     Children={
  115.       {
  116.         X=1,
  117.         Width="100%",
  118.         Y=2,
  119.         Name="HelloLabel",
  120.         Type="Label",
  121.         Text="Bootloader Setup",
  122.         Align="Center",
  123.       },
  124.       {
  125.         X=2,
  126.         Y=4,
  127.         Name="DebugMode",
  128.         Type="Button",
  129.         Text="Debug Mode: Disabled",
  130.       },
  131.       {
  132.         X="1",
  133.         Y="100%",
  134.     Align = "Right",
  135.         Name="Save",
  136.         Type="Button",
  137.         Text="Save",
  138.       },
  139.       {
  140.         X=2,
  141.         Y=6,
  142.         Width=22,
  143.     Type="TextBox",
  144.     Name="DPath",
  145.         Placeholder="Default Path",
  146.         Active=false
  147.       },
  148.       {
  149.         X=2,
  150.         Y=8,
  151.         Width=22,
  152.         Type="TextBox",
  153.         Name="WaitT",
  154.         Placeholder="Wait Time",
  155.         Active=false,
  156.       },
  157.       {
  158.         X="88%",
  159.         Y="100%",
  160.     Align = "Left",
  161.         Name="Reboot",
  162.         Type="Button",
  163.         Text="Reboot",
  164.       },
  165.     },
  166.     BackgroundColour='white'
  167. } ]]
  168.         f.write(payload)
  169.         f.close()
  170.     end
  171. end
  172.  
  173. function startup()
  174.   if fs.exists('startup') then
  175.     local f = fs.open('startup', 'r')
  176.     local ck = f.readLine()
  177.     debug(ck)
  178.     if ck ~= "--#--" then
  179.       --to preserve existing startup, uncomment
  180.       --fs.move('startup', 'startup.boot')
  181.     end
  182.   end
  183.   local f = fs.open(shell.getRunningProgram(), 'r')
  184.   local ck = f.readLine()
  185.   f.close()
  186.   local f = fs.open(shell.getRunningProgram(), 'r')
  187.   if ck == "--#--" then
  188.     debug('sgrp = --#--')
  189.     local w = fs.open('startup', 'w')
  190.     w.write(f.readAll())
  191.     w.close()
  192.     --debug('New Startup Created')
  193.   end
  194.   f.close()
  195.   --sleep(5)
  196. end
  197.  
  198. function debug(txt)
  199.   if dev == 'true' or dev then print(txt) end
  200. end
  201.  
  202. function cfill(c)
  203.   if term.isColor() ~= true then c = colors.black end
  204.   term.setCursorPos(1, 1)
  205.   term.setBackgroundColor(c)
  206.   term.setTextColor(c)
  207.   for i = 1, 24 do
  208.     print("=========================================================")
  209.   end
  210.   term.setCursorPos(1, 1)  
  211. end
  212.  
  213. function kt()
  214.   r = true
  215.   debug('Keypress Listener Started')
  216.   x, y = term.getSize()
  217.   x1, y1 = term.getCursorPos()
  218.   term.setCursorPos(x/2-11, y)
  219.   print("DELETE for more options")
  220.   if term.isColor() then
  221.     term.setCursorPos(x/2-10, y-2)
  222.     print("ESCAPE to enter setup")
  223.   end
  224.   while true do
  225.   os.startTimer(.1)
  226.   term.setCursorPos(1, y1+1)
  227.   print("Time Remaining: ")
  228.   term.setCursorPos(17, y1+1)
  229.   print("                  ")
  230.   term.setCursorPos(17, y1+1)
  231.   print(WaitTime - counter)
  232.   local v, k = os.pullEvent()
  233.   r = 'Continue'
  234.   if v == 'key' then
  235.     if k == keys.enter then r = 'Continue' debug('Enter Pressed') break end
  236.     if k == keys.delete then r = "Menu" debug('Delete Pressed') break end
  237.     if k == 1 then r = "Setup" debug("Escape Pressed") break end
  238.     if k == keys.tab then os.loadAPI('/rom/programs/lua') os.reboot() end    
  239.   end
  240.   sleep(.1)
  241.   counter = counter + 1
  242.   if counter >= WaitTime then break end
  243.   end
  244.   return r
  245. end
  246.  
  247.  
  248. function find()
  249.   local results = {}
  250.   if fs then
  251.     local suffix = {'boot', 'start', 'startup', 'load', 'bin'}
  252.     for k, v in pairs(suffix) do
  253.       debug('searching *.' .. v)
  254.       local res = {}
  255.       res = fs.find('*.' .. v)
  256.       for g, h in pairs(res) do
  257.         table.insert(results, h)
  258.       end
  259.     end
  260.     debug('')
  261.   else
  262.     error("NO FS API")
  263.   end
  264.   return results
  265. end
  266.  
  267. function select(l)
  268.   debug(l[1] .. " Selected")
  269.   return l[1]
  270. end
  271.  
  272. function exec(file)
  273.   local f = fs.open(file, 'r')
  274.   local r = f.readAll()
  275.   f.close()
  276.   local c = loadstring(r)
  277.   setfenv(c, getfenv())
  278.   if term then
  279.     term.clear()
  280.     term.setCursorPos(1, 1)
  281.     term.setBackgroundColor(colors.black)
  282.     cfill(colors.black)
  283.     term.setTextColor(colors.white)
  284.   else
  285.     error("NO TERM API")
  286.   end
  287.   c()
  288. end
  289.  
  290.  
  291. function boot()
  292.   local r = "Continue"
  293.   if ID ~= nil then function os.getComputerID() return ID end end
  294.   print('Searching...')
  295.   local f = find()
  296.   if #f < 1 then
  297.     term.setTextColor(colors.red)
  298.     print('No Bootable Medium Found')
  299.     term.setTextColor(colors.white)
  300.     sleep(2)
  301.     r = false
  302.   else
  303.     local p = ''
  304.     if #f > 1 or #f < 1 then p = 's' end
  305.     print('found ' .. #f .. " file" .. p)
  306.     for v, i in pairs(f) do
  307.       print('    ' .. i)
  308.     end
  309.     local chosen = select(f)
  310.         if defaultPath ~= nil and #defaultPath >= 1 then chosen = defaultPath end    
  311.         print('Selecting: ' .. chosen)
  312.     debug('')
  313.     local k = kt()
  314.     if k == "Continue" and checkSecureBoot(chosen) then
  315.       exec(chosen)
  316.     elseif k == "Menu" then
  317.       r = "Menu"
  318.     elseif k == "Setup" then
  319.       r = "Setup"
  320.     else
  321.       term.setTextColor(colors.red)
  322.       print("WARNING: IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING VERY NASTY, PLEASE REBOOT AND MAKE SURE THAT", string.upper(chosen), "HAS NOT BEEN TAMPERED WITH.")
  323.       os.pullEvent("HALT")
  324.     end
  325.   end
  326.   return r
  327. end
  328.  
  329. function setup()
  330.   local bedrockPath='/' if OneOS then OneOS.LoadAPI('/System/API/Bedrock.lua', false)elseif fs.exists(bedrockPath..'/Bedrock')then os.loadAPI(bedrockPath..'/Bedrock')else if http then print('Downloading Bedrock...')local h=http.get('http://pastebin.com/raw.php?i=0MgKNqpN')if h then local f=fs.open(bedrockPath..'/Bedrock','w')f.write(h.readAll())f.close()h.close()os.loadAPI(bedrockPath..'/Bedrock')else error('Failed to download Bedrock. Is your internet working?') end else error('This program needs to download Bedrock to work. Please enable HTTP.') end end if Bedrock then Bedrock.BasePath = bedrockPath Bedrock.ProgramPath = shell.getRunningProgram() end
  331.  
  332.     ViewInsert()
  333.     local program = Bedrock:Initialise()
  334.  
  335.        
  336.     program:Run(function()
  337.         DevMode = dev
  338.         --DebugMode Button
  339.         if DevMode == false then
  340.             program:GetObject('DebugMode').Text = "Debug Mode: Disabled"
  341.         else
  342.             program:GetObject('DebugMode').Text = "Debug Mode:  Enabled"
  343.         end
  344.         program:GetObject('DebugMode').OnClick = function(self, event, side, x, y)
  345.             if DevMode == false then DevMode = true else DevMode = false end
  346.             dev = DevMode
  347.  
  348.             if DevMode == false then
  349.                 program:GetObject('DebugMode').Text = "Debug Mode: Disabled"
  350.             else
  351.                 program:GetObject('DebugMode').Text = "Debug Mode:  Enabled"
  352.             end
  353.         end
  354.         --End
  355.         --Reboot Button
  356.         program:GetObject('Reboot').OnClick = function(self, event, side, x, y) os.reboot() end
  357.         --End
  358.         --Default Path
  359.         function getpath()
  360.             local path = program:GetObject('DPath').Text
  361.             local safe = false         
  362.             if path ~= nil and fs.exists(path) then
  363.                 safe = true
  364.             elseif path ~= nil and fs.exists(path) ~= true then
  365.                 program:DisplayAlertWindow('Error', 'Invalid Path', {'OK'}, function(value) end)
  366.                 safe = false
  367.                 path = ""
  368.             elseif path == nil then
  369.                 safe = true
  370.                 path = ""
  371.             end
  372.             msg = {}
  373.             msg.safe = safe
  374.             msg.path = tostring("'" .. path .. "'")
  375.             return msg
  376.         end
  377.         --End
  378.  
  379.         --Wait Time
  380.         function getwait()
  381.             local path = program:GetObject('WaitT').Text
  382.             local safe = false         
  383.             if path ~= nil and tonumber(path) then
  384.                 safe = true
  385.             elseif path == "" then
  386.                 safe = true
  387.                 path = "15"
  388.             else
  389.                 program:DisplayAlertWindow('Error', 'Invalid Wait Time', {'OK'}, function(value) end)
  390.                 safe = false
  391.                 path = ""
  392.  
  393.             end
  394.             msg = {}
  395.             msg.safe = safe
  396.             msg.value = path
  397.             return msg
  398.         end
  399.         --End
  400.  
  401.         --Save Button
  402.         program:GetObject('Save').OnClick = function(self, event, side, x, y)
  403.             local ne = true        
  404.             local p = getpath()
  405.             local WTV = getwait()          
  406.             local path = ""
  407.             local WV = ""          
  408.             local out = {}
  409.            
  410.             if p['safe'] then   path = p['path'] else ne = false end
  411.             if WTV['safe'] then WV = WTV['value'] else ne = false end
  412.    
  413.             --vars
  414.                 out.dev = DevMode
  415.                 out.defaultPath = path
  416.                 out.WaitTime = WV
  417.             --end
  418.  
  419.             if ne then local f = fs.open(".bcfg", 'w') f.write(textutils.serialize(out)) f.close() end
  420.  
  421.             if ne then program:DisplayAlertWindow('Success', 'Settings Saved', {'OK'}, function(value) end) end
  422.            
  423.         end
  424.  
  425.  
  426.     end)
  427.    
  428.  
  429. end
  430.  
  431. function menu()
  432.   term.clear()
  433.   cfill(colors.blue)
  434.   if term.isColor then term.setBackgroundColor(colors.blue) end
  435.   term.setTextColor(colors.white)
  436.   local x, y = term.getSize()
  437.   term.setCursorPos((x/2)-8, 1)
  438.   print('Select a boot file')
  439.   local x, y = term.getSize()
  440.   term.setCursorPos(1,4)
  441.   dev = false
  442.   local f = find()
  443.   dev = true
  444.   for i, v in pairs(f) do
  445.     print(i .. '. ' .. v)
  446.   end
  447.   print('0. Other')
  448.  
  449.   print('')
  450.   print('')
  451.   write('#> ')
  452.   local n = read()
  453.   if tonumber(n) == 0 then
  454.     write('Path> ')
  455.     local o = read()
  456.     if fs.exists(o) then
  457.       exec(o)
  458.     else
  459.       print('file does not exist')
  460.       sleep(2)
  461.       menu()
  462.     end
  463.   elseif tonumber(n) == nil or tonumber(n)>#f or tonumber(n)<1 then
  464.     print('Invalid boot file')
  465.     menu()
  466.   else
  467.     local s = f[tonumber(n)]
  468.     print('Selecting ' .. s)
  469.     sleep(1)
  470.     exec(s)
  471.   end
  472. end
  473.  
  474. argv = {...}
  475.  
  476. function main()
  477.  
  478. if #argv > 0 then
  479. --Someones trying to configure via commandline
  480.   local cfg = {}
  481.   if fs.exists('.bcfg') then
  482.     local cfgb = fs.open('.bcfg', 'r')
  483.     cfg = cfgb.readAll()
  484.     cfgb.close()
  485.     cfg = textutils.unserialise(cfg)
  486.   end
  487.     --f, s = string.match(v, "(%w+)=(%w+)")
  488.     local f = argv[1]
  489.     local t = argv[2]
  490.     cfg[f] = t
  491.     print("Inserted ", t, " into ", f)
  492.  
  493.   local cfgb = fs.open('.bcfg', 'w')
  494.   cfgb.write(textutils.serialize(cfg))
  495.   cfgb.close()
  496.  
  497. elseif shell.getRunningProgram() ~= nil then
  498.  
  499.   if shell.getRunningProgram() ~= 'startup' or fs.exists('startup') == false then
  500.     startup()
  501.     os.reboot()
  502.   else
  503.     LoadCFG()
  504.     local b = boot()
  505.     if b == "Continue" then
  506.       --booted successfully
  507.     elseif b == "Menu" then
  508.       --launch menu(
  509.       menu()
  510.     elseif b == "Setup" then
  511.       --start setup
  512.       setup()
  513.     end
  514.   end
  515. else
  516. --launch a shell
  517. os.loadAPI('/rom/programs/lua')
  518. end
  519. end
  520.  
  521. local stat, err = pcall(main)
  522. if not stat then fuck(err) end
RAW Paste Data