mirror of
https://github.com/20kdc/OC-KittenOS.git
synced 2024-11-16 23:48:05 +11:00
Compare commits
79 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9d152bb994 | ||
|
d2ad9ce4eb | ||
|
d623375c04 | ||
|
0f333b9c2f | ||
|
85869aa80d | ||
|
6fc56b4d64 | ||
|
f083efd9a3 | ||
|
2ea52fc362 | ||
|
2dbc3cdb0e | ||
|
2fe4884558 | ||
|
dcd7154ec2 | ||
|
881193aa9a | ||
|
e308f54ad7 | ||
|
cbe40da3bb | ||
|
8bd316338b | ||
|
3dbea9d3f7 | ||
|
2ebc0840ac | ||
|
da58c88d0d | ||
|
fe17b0fb93 | ||
|
c9157a1b7c | ||
|
ca4b6e5df2 | ||
|
7d1f6d2cae | ||
|
a585ce4a75 | ||
|
3ed1cebe25 | ||
|
7c70a1128c | ||
|
5ac8f9ff11 | ||
|
f761ad5824 | ||
|
aef0043d4a | ||
|
151097cdce | ||
|
bfcb4f9028 | ||
|
cc55e8a66f | ||
|
3c4a3147c4 | ||
|
bc4d626b4e | ||
|
dd21abe8fa | ||
|
22c1c211ef | ||
|
7840f0a231 | ||
|
339571ee9b | ||
|
479412a5bb | ||
|
d2ee505316 | ||
|
f5ba0489b2 | ||
|
20c016f068 | ||
|
fab88f137c | ||
|
7680aa7579 | ||
|
429de87a61 | ||
|
7307eb30a4 | ||
|
0d9583fcff | ||
|
375995c2d3 | ||
|
efae7716da | ||
|
27bd71f9e4 | ||
|
3d3517bc53 | ||
|
916d127337 | ||
|
630c5f57f5 | ||
|
3502cdedc2 | ||
|
21294872f3 | ||
|
71a0aa0b08 | ||
|
99cb58d9fc | ||
|
324ed86335 | ||
|
13d3abfd26 | ||
|
27f7fe35da | ||
|
6255587090 | ||
|
f903a16166 | ||
|
347bebdb03 | ||
|
8f86dfd730 | ||
|
76448b8187 | ||
|
b320dfe083 | ||
|
3bc323e268 | ||
|
1e3bf096d5 | ||
|
6237871d36 | ||
|
d371044146 | ||
|
050941a513 | ||
|
3ba0792dfe | ||
|
7ca2c26979 | ||
|
ccb9c3b279 | ||
|
8ab47c96b3 | ||
|
e1530057a6 | ||
|
9254745a33 | ||
|
4c12bb548a | ||
|
46d60df1ec | ||
|
e75cd20aa4 |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,9 +1,8 @@
|
|||||||
# This is released into the public domain.
|
# This is released into the public domain.
|
||||||
# No warranty is provided, implied or otherwise.
|
# No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
# leaving in preSH.tar.gz for anyone who's interested
|
|
||||||
# in how NOT to do compression
|
|
||||||
code.tar
|
code.tar
|
||||||
|
code/data/app-claw/*
|
||||||
work.tar
|
work.tar
|
||||||
work
|
work
|
||||||
work/
|
work/
|
||||||
@ -20,6 +19,10 @@ repobuild/*/*
|
|||||||
repobuild/*/*/
|
repobuild/*/*/
|
||||||
repobuild/*/*/*
|
repobuild/*/*/*
|
||||||
|
|
||||||
|
laboratory/ocemu.cfg
|
||||||
|
laboratory/bios.lua
|
||||||
|
laboratory/data
|
||||||
|
laboratory/log
|
||||||
laboratory/*/
|
laboratory/*/
|
||||||
laboratory/*/*
|
laboratory/*/*
|
||||||
laboratory/*/*/
|
laboratory/*/*/
|
||||||
@ -30,7 +33,9 @@ laboratory/*/*/*/*
|
|||||||
inst.lua
|
inst.lua
|
||||||
# Available as the respective release
|
# Available as the respective release
|
||||||
inst-gold.lua
|
inst-gold.lua
|
||||||
com2/code.tar.bd
|
# Compression stuff
|
||||||
|
inst/iSymTab
|
||||||
|
# internal
|
||||||
upldr.sh
|
upldr.sh
|
||||||
upldr-dev.sh
|
upldr-dev.sh
|
||||||
upldr-gold.sh
|
upldr-gold.sh
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
|
||||||
Hash: SHA256
|
|
||||||
|
|
||||||
- -- To Microsoft.
|
|
||||||
- -- You deserve to get yourselves investigated by Trading Standards.
|
|
||||||
- -- I don't mean that in a "and then everything comes out okay" way,
|
|
||||||
- -- I mean that as in a "you deserve to be legitimately threatened with being shutdown" way.
|
|
||||||
- -- See that MultiMC issue, #2223, about the Windows 10 thing?
|
|
||||||
- -- That's the beginnings of what you've caused, and don't you dare deny the intent.
|
|
||||||
- -- In what world is swapping around the names of two products, both in
|
|
||||||
- -- active sales no less, to get one to be chosen over the other by an
|
|
||||||
- -- uninformed buyer *not illegal*?
|
|
||||||
|
|
||||||
- -- To anyone else, I say this.
|
|
||||||
- -- If you're affected by this, just pirate the Java edition.
|
|
||||||
- -- You have been affected by what I can say without contradiction is a campaign of lies.
|
|
||||||
- -- Deliberate or otherwise, but history would point in favour of a calculated attack.
|
|
||||||
- -- Take what is frankly rightfully yours.
|
|
||||||
- -- Oh, Microsoft, did you not like that? I don't care, and it is plainly obvious why I shouldn't care.
|
|
||||||
|
|
||||||
- -- To the Mojang team - the *real* Mojang team (Anyone working on Bedrock is exempt) - I pity you,
|
|
||||||
- -- but I'm afraid I have to recommend this course of action.
|
|
||||||
- -- There is no other way. I'm sure you already know what Microsoft is like first-hand.
|
|
||||||
- -- I'm sure you've read the reports and you know Microsoft will lobby their way
|
|
||||||
- -- past anything I could even suggest to any politician, if it even got that far.
|
|
||||||
- -- I'm sure you can already see your presumed redundancies coming, and I doubt I hasten it.
|
|
||||||
- -- And frankly, preventing Microsoft from abusing Minecraft as a lock-in tactic in whatever way I can
|
|
||||||
- -- takes priority.
|
|
||||||
|
|
||||||
- -- To those who doubted what I said to them when I said it to them,
|
|
||||||
- -- to those who doubt me now, know this. It's happening, it's real,
|
|
||||||
- -- there is proof with basic searches.
|
|
||||||
|
|
||||||
- -- To those who are ignorant, and yet scared to let anyone leave them,
|
|
||||||
- -- THOSE WITHOUT WINDOWS 10 ON THEIR DESKTOPS WON'T BE ABLE TO JOIN YOU
|
|
||||||
- -- ON MC IF THIS GOES AS THEY LIKELY INTEND.
|
|
||||||
- -- You may doubt my "likely", but remember this:
|
|
||||||
- -- We thought they would do this long ago, when Microsoft bought Mojang.
|
|
||||||
- -- It took time, yes. But it started to happen and when it did, everything started moving into place.
|
|
||||||
- -- The "Better Together" (unless on a non-Windows 10 desktop) update was simply the end of a journey.
|
|
||||||
- -- When I look back, the guesses - mine and others - as to what they will do next have been delayed,
|
|
||||||
- -- but they are occurring, along with new horrors that I did not expect,
|
|
||||||
- -- like the commercialization of that offered by mods for free here on the "Java Edition".
|
|
||||||
- -- You can argue all you like about how they put work into that stuff,
|
|
||||||
- -- fact is, Bedrock is a downgrade.
|
|
||||||
- -- You could argue about performance, but - Mods fix the performance issues,
|
|
||||||
- -- and they aren't exactly hard to install. Download Forge installer. Run Forge installer.
|
|
||||||
- -- Copy one file. Done.
|
|
||||||
- -- You cannot argue about playerbase - people are left behind, unable to go to Bedrock.
|
|
||||||
- -- Even if you claim it's their fault for using Windows 10, how much have you somehow missed
|
|
||||||
- -- about Windows 10's various nastiness? There's a laptop basically unusable for anything real-time here
|
|
||||||
- -- on Windows 10 because of an update that screwed it over, and no, a reset did not fix it. Nothing did.
|
|
||||||
- -- Except moving it to another OS, but of course, that wouldn't work so well if Bedrock was a concern.
|
|
||||||
- -- Moddability has been, and probably always will be, destroyed on Bedrock.
|
|
||||||
- -- Sure, you'll eventually get some more and more access,
|
|
||||||
- -- but there's a reason the way Minecraft modding went
|
|
||||||
- -- lead to the inventive and amazing mods out there,
|
|
||||||
- -- and it certainly wasn't a bunch of "behavior packs"!
|
|
||||||
|
|
||||||
- -- To those who wonder what the hell this is doing here,
|
|
||||||
- -- I don't care. Feel free to remove the file from your local machines,
|
|
||||||
- -- but if you send a PR asking for its removal, I *will* reject it instantly.
|
|
||||||
|
|
||||||
- -- -20kdc
|
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQEzBAEBCAAdFiEE4HrK8U+8321iGlEUALn5S4V/2fkFAlrafToACgkQALn5S4V/
|
|
||||||
2fkW/wf/afn8PjeCYyNOWNhGmELNO5dL3eWaBb86KAiDZXMYPmCifDiXOOmYeq2t
|
|
||||||
3cqcDXujOQJN7PE8RBzrVSIm2kjLtQXoFuhww6A9p3LuyXdPT0WykMroPM5xYrrH
|
|
||||||
7c6VtaWkXngHn/Z/aLgIDsveW/LiHqG5a8N98XdPivlRgfsBPo5+/wv84gcnAGzL
|
|
||||||
vJURI/GMEuFj+Bg6Vw0fiiYF4DAVKSdSb830bW4flFTwXBHOL8SiUbEDBX1W5nj1
|
|
||||||
KbnIhnXdy/rGbjsVUlpnDIyL+IdTyRwLyxYpjvHqpdb0RjALCw+b6uzQ6feOUb2/
|
|
||||||
RsDIy5cRGY4k2sSP+yFByvNR34HphA==
|
|
||||||
=uPTk
|
|
||||||
-----END PGP SIGNATURE-----
|
|
60
README.md
60
README.md
@ -1,3 +1,51 @@
|
|||||||
|
# ATTENTION! WARNING! ETCETERA!!!
|
||||||
|
|
||||||
|
AS OF 11TH JULY 2022, ALL SUPPORT AND MAINTENANCE ON THIS REPOSITORY HAS BEEN DROPPED.
|
||||||
|
|
||||||
|
Microsoft finally turned off whatever mechanism PolyMC was using to let people play multiplayer on Mojang accounts.
|
||||||
|
|
||||||
|
Use UltimMC. Use something like https://modrinth.com/mod/easyauth . Host your servers this way.
|
||||||
|
|
||||||
|
Microsoft have proven they are willing to remove a bought product off your hands if you don't agree to their new rules about it.
|
||||||
|
|
||||||
|
They have proven that "buying" something off of them means nothing and anything you've "bought" from Mojang means nothing.
|
||||||
|
|
||||||
|
*They have stolen what they have been paid money for. Therefore they don't deserve to have anything bought off them at all.*
|
||||||
|
|
||||||
|
And before any of you go "just migrate", look at the warning signs as to the ban systems.
|
||||||
|
|
||||||
|
Maybe watch FitMC's video: https://www.youtube.com/watch?v=rdoFUhd0EkI
|
||||||
|
|
||||||
|
Or maybe read the migration horror stories:
|
||||||
|
|
||||||
|
+ https://www.reddit.com/r/xbox/comments/sscoa7/does_anyone_have_an_idea_why_was_i_locked_out_of/
|
||||||
|
+ https://news.ycombinator.com/item?id=31551846
|
||||||
|
+ https://answers.microsoft.com/en-us/xbox/forum/all/im-locked-out-of-minecraft-after-migrating-my/9f1f64cb-6a2d-4cd2-abb8-0010a6bc6f31
|
||||||
|
+ https://www.reddit.com/r/Minecraft/comments/we8asn/why_microsoft_ever_since_i_was_forced_to_migrate/
|
||||||
|
+ even rekrap1 got bitten by this: https://www.youtube.com/watch?v=rzPYH98TTMM
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
. OLD README BELOW
|
||||||
|
|
||||||
# KittenOS NEO
|
# KittenOS NEO
|
||||||
|
|
||||||
As per usual, no warranty, not my responsibility if this breaks, or if you somehow try to run it on an actual (non-OpenComputers) computer.
|
As per usual, no warranty, not my responsibility if this breaks, or if you somehow try to run it on an actual (non-OpenComputers) computer.
|
||||||
@ -36,12 +84,16 @@ It would be really nice if, if I have screwed up, that you tell me how.
|
|||||||
Preferably with a solution that fits the technological constraints.
|
Preferably with a solution that fits the technological constraints.
|
||||||
|
|
||||||
Licensing in this project is rather fluid,
|
Licensing in this project is rather fluid,
|
||||||
but everything in code/ is unconditionally under the following license:
|
but everything that is not in `repository/` is unconditionally under the following license:
|
||||||
|
|
||||||
This is released into the public domain.
|
Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
This will be referred to as "Public Domain".
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
|
||||||
|
This will be referred to as "BSD0".
|
||||||
|
|
||||||
It should be considered equivalent to CC0, and this is the intent,
|
It should be considered equivalent to CC0, and this is the intent,
|
||||||
but it is smaller, which is somewhat important when optimizing for size.
|
but it is smaller, which is somewhat important when optimizing for size.
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- This program tries to crunch down the installer a bit further.
|
|
||||||
-- Specific target in mind, it has no support for string escapes.
|
|
||||||
-- It also does this:
|
|
||||||
for i = 1, 3 do
|
|
||||||
print(io.read())
|
|
||||||
end
|
|
||||||
|
|
||||||
local sequences = {
|
|
||||||
{"\n", " "},
|
|
||||||
{" ", " "},
|
|
||||||
{" #", "#"},
|
|
||||||
{"# ", "#"},
|
|
||||||
{" ,", ","},
|
|
||||||
{", ", ","},
|
|
||||||
{" (", "("},
|
|
||||||
{"( ", "("},
|
|
||||||
{" )", ")"},
|
|
||||||
{") ", ")"},
|
|
||||||
{" <", "<"},
|
|
||||||
{"< ", "<"},
|
|
||||||
{" >", ">"},
|
|
||||||
{"> ", ">"},
|
|
||||||
{" *", "*"},
|
|
||||||
{"* ", "*"},
|
|
||||||
{" ~", "~"},
|
|
||||||
{"~ ", "~"},
|
|
||||||
{" /", "/"},
|
|
||||||
{"/ ", "/"},
|
|
||||||
{" %", "%"},
|
|
||||||
{"% ", "%"},
|
|
||||||
{" =", "="},
|
|
||||||
{"= ", "="},
|
|
||||||
{" -", "-"},
|
|
||||||
{"- ", "-"},
|
|
||||||
{" +", "+"},
|
|
||||||
{"+ ", "+"},
|
|
||||||
{".. ", ".."},
|
|
||||||
{" ..", ".."},
|
|
||||||
{"\"\" ", "\"\""},
|
|
||||||
{"=0 t", "=0t"},
|
|
||||||
{">0 t", ">0t"},
|
|
||||||
{">1 t", ">1t"},
|
|
||||||
{"=1 w", "=1w"},
|
|
||||||
{"=380 l", "=380l"},
|
|
||||||
{"=127 t", "=127t"},
|
|
||||||
{"=128 t", "=128t"},
|
|
||||||
{">255 t", ">255t"},
|
|
||||||
{"=512 t", "=512t"}
|
|
||||||
}
|
|
||||||
|
|
||||||
local function pass(buffer)
|
|
||||||
local ob = ""
|
|
||||||
local smode = false
|
|
||||||
while #buffer > 0 do
|
|
||||||
if not smode then
|
|
||||||
local ds = true
|
|
||||||
while ds do
|
|
||||||
ds = false
|
|
||||||
for _, v in ipairs(sequences) do
|
|
||||||
if buffer:sub(1, #(v[1])) == v[1] then
|
|
||||||
buffer = v[2] .. buffer:sub(#(v[1]) + 1)
|
|
||||||
ds = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local ch = buffer:sub(1, 1)
|
|
||||||
buffer = buffer:sub(2)
|
|
||||||
ob = ob .. ch
|
|
||||||
if ch == "\"" then
|
|
||||||
smode = not smode
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ob
|
|
||||||
end
|
|
||||||
local op = io.read("*a")
|
|
||||||
while true do
|
|
||||||
local np = pass(op)
|
|
||||||
if np == op then
|
|
||||||
io.write(np)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
op = np
|
|
||||||
end
|
|
75
claw/C2-Format.md
Normal file
75
claw/C2-Format.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# Claw2 Formats
|
||||||
|
|
||||||
|
## .c2l format
|
||||||
|
|
||||||
|
The .c2l format is the server package list for Claw2.
|
||||||
|
|
||||||
|
In an exception to the rule, this file only exists on the server.
|
||||||
|
|
||||||
|
It is used solely in the main package list panel.
|
||||||
|
|
||||||
|
It is a file made up of lines.
|
||||||
|
|
||||||
|
Each line contains a package name, followed by a dot, followed by the package version.
|
||||||
|
|
||||||
|
## .V.c2p format
|
||||||
|
|
||||||
|
The .V.c2p (where V is the version) format is the entire contents of the package view panel,
|
||||||
|
as text, with newlines, in UTF-8.
|
||||||
|
|
||||||
|
This is used when a package is selected in Claw2.
|
||||||
|
|
||||||
|
## .c2x format
|
||||||
|
|
||||||
|
The .c2x format is the actual installation script for the package.
|
||||||
|
|
||||||
|
It is executed by svc-claw-worker.
|
||||||
|
|
||||||
|
It's loaded in all-at-once, then it's gmatched
|
||||||
|
with the pattern [^\n]+.
|
||||||
|
|
||||||
|
A line starting with "?" represents a dependency.
|
||||||
|
|
||||||
|
A line starting & ending with "/" represents a directory creation.
|
||||||
|
|
||||||
|
And a line starting with "+" represents a file.
|
||||||
|
|
||||||
|
Package metadata is not implied.
|
||||||
|
|
||||||
|
Thus, a valid .c2x is:
|
||||||
|
|
||||||
|
```
|
||||||
|
?neo
|
||||||
|
/apps/
|
||||||
|
+apps/app-carrot.0.c2p
|
||||||
|
+apps/app-carrot.c2x
|
||||||
|
```
|
||||||
|
|
||||||
|
## Claw2 Architecture
|
||||||
|
|
||||||
|
app-claw is a very dumb client, but the only thing that'll bother
|
||||||
|
to parse a .c2l (because it has package list/search),
|
||||||
|
and the only thing that cares about version numbers.
|
||||||
|
|
||||||
|
The purpose of it is to provide an older-CLAW-style GUI.
|
||||||
|
|
||||||
|
It *may* take an argument, in which case a package panel is opened,
|
||||||
|
otherwise the main search panel is opened.
|
||||||
|
|
||||||
|
When it wants to do anything, it shuts itself down, running svc-claw-worker.
|
||||||
|
|
||||||
|
svc-app-claw-worker does all package consistency & such work.
|
||||||
|
|
||||||
|
It can only be run from app-claw, and runs app-claw after it's done.
|
||||||
|
|
||||||
|
It takes 5 arguments:
|
||||||
|
|
||||||
|
1. The target filesystem proxy.
|
||||||
|
2. The target package name. This package is viewed in app-claw after completion.
|
||||||
|
3. The source to download files from.
|
||||||
|
If nil, the package is being deleted.
|
||||||
|
Otherwise, can either be a proxy or a string.
|
||||||
|
Proxy means it's a filesystem,
|
||||||
|
string means it's an internet base.
|
||||||
|
4. Checked flag
|
||||||
|
5. primary inet card proxy, if any
|
38
claw/clawconv.lua
Normal file
38
claw/clawconv.lua
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- CLAW local.lua converter. Expects to be run from outermost folder.
|
||||||
|
|
||||||
|
local target = ...
|
||||||
|
|
||||||
|
local serial = loadfile("code/libs/serial.lua")()
|
||||||
|
|
||||||
|
for k, v in pairs(serial.deserialize(io.read("*a"))) do
|
||||||
|
print(k .. "." .. v.v .. ".c2p")
|
||||||
|
print(k .. ".c2x")
|
||||||
|
local f2 = io.open(target .. k .. "." .. v.v .. ".c2p", "wb")
|
||||||
|
f2:write(k .. "\n")
|
||||||
|
f2:write(v.desc .. "\n")
|
||||||
|
f2:write("v" .. v.v .. " deps " .. table.concat(v.deps, ", "))
|
||||||
|
f2:close()
|
||||||
|
f2 = io.open(target .. k .. ".c2x", "wb")
|
||||||
|
for _, vx in ipairs(v.deps) do
|
||||||
|
f2:write("?" .. vx .. "\n")
|
||||||
|
end
|
||||||
|
for _, vx in ipairs(v.dirs) do
|
||||||
|
f2:write("/" .. vx .. "\n")
|
||||||
|
end
|
||||||
|
for _, vx in ipairs(v.files) do
|
||||||
|
f2:write("+" .. vx .. "\n")
|
||||||
|
end
|
||||||
|
f2:write("/data\n")
|
||||||
|
f2:write("/data/app-claw\n")
|
||||||
|
f2:write("+data/app-claw/" .. k .. ".c2x\n")
|
||||||
|
f2:write("+data/app-claw/" .. k .. "." .. v.v .. ".c2p\n")
|
||||||
|
f2:close()
|
||||||
|
end
|
||||||
|
|
@ -1,9 +1,14 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
["neo"] = {
|
["neo"] = {
|
||||||
desc = "KittenOS NEO Kernel & Base Libs",
|
desc = "KittenOS NEO Kernel & Base Libs",
|
||||||
v = 4,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
||||||
@ -18,6 +23,7 @@ return {
|
|||||||
"libs/serial.lua",
|
"libs/serial.lua",
|
||||||
"libs/fmttext.lua",
|
"libs/fmttext.lua",
|
||||||
"libs/neoux.lua",
|
"libs/neoux.lua",
|
||||||
|
"libs/lineedit.lua",
|
||||||
"libs/braille.lua",
|
"libs/braille.lua",
|
||||||
"libs/bmp.lua",
|
"libs/bmp.lua",
|
||||||
"libs/sys-filewrap.lua",
|
"libs/sys-filewrap.lua",
|
||||||
@ -26,7 +32,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-init"] = {
|
["neo-init"] = {
|
||||||
desc = "KittenOS NEO / sys-init (startup)",
|
desc = "KittenOS NEO / sys-init (startup)",
|
||||||
v = 2,
|
v = 11,
|
||||||
deps = {
|
deps = {
|
||||||
"neo",
|
"neo",
|
||||||
"neo-icecap",
|
"neo-icecap",
|
||||||
@ -41,7 +47,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-launcher"] = {
|
["neo-launcher"] = {
|
||||||
desc = "KittenOS NEO / Default app-launcher",
|
desc = "KittenOS NEO / Default app-launcher",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -54,7 +60,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-everest"] = {
|
["neo-everest"] = {
|
||||||
desc = "KittenOS NEO / Everest (windowing)",
|
desc = "KittenOS NEO / Everest (windowing)",
|
||||||
v = 3,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -67,7 +73,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-icecap"] = {
|
["neo-icecap"] = {
|
||||||
desc = "KittenOS NEO / Icecap",
|
desc = "KittenOS NEO / Icecap",
|
||||||
v = 3,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -84,7 +90,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-secpolicy"] = {
|
["neo-secpolicy"] = {
|
||||||
desc = "KittenOS NEO / Secpolicy",
|
desc = "KittenOS NEO / Secpolicy",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
||||||
@ -96,7 +102,7 @@ return {
|
|||||||
},
|
},
|
||||||
["neo-coreapps"] = {
|
["neo-coreapps"] = {
|
||||||
desc = "KittenOS NEO Core Apps",
|
desc = "KittenOS NEO Core Apps",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -105,40 +111,39 @@ return {
|
|||||||
},
|
},
|
||||||
files = {
|
files = {
|
||||||
"apps/app-textedit.lua",
|
"apps/app-textedit.lua",
|
||||||
|
"apps/app-batmon.lua",
|
||||||
"apps/app-control.lua",
|
"apps/app-control.lua",
|
||||||
"apps/app-taskmgr.lua"
|
"apps/app-taskmgr.lua"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
["app-klogo"] = {
|
["app-bmpview"] = {
|
||||||
desc = "KittenOS NEO Logo shower",
|
desc = "KittenOS NEO .bmp viewer",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo",
|
"neo",
|
||||||
"app-klogo-logo"
|
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
||||||
"apps"
|
"apps"
|
||||||
},
|
},
|
||||||
files = {
|
files = {
|
||||||
"apps/app-klogo.lua",
|
"apps/app-bmpview.lua",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
["app-klogo-logo"] = {
|
["neo-logo"] = {
|
||||||
desc = "KittenOS NEO Logo (data)",
|
desc = "KittenOS NEO Logo (data)",
|
||||||
v = 4,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
||||||
"data",
|
"docs"
|
||||||
"data/app-klogo"
|
|
||||||
},
|
},
|
||||||
files = {
|
files = {
|
||||||
"data/app-klogo/logo.bmp"
|
"docs/logo.bmp"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
["app-flash"] = {
|
["app-flash"] = {
|
||||||
desc = "KittenOS NEO EEPROM Flasher",
|
desc = "KittenOS NEO EEPROM Flasher",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -151,7 +156,7 @@ return {
|
|||||||
},
|
},
|
||||||
["app-wget"] = {
|
["app-wget"] = {
|
||||||
desc = "KittenOS Web Retriever",
|
desc = "KittenOS Web Retriever",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
@ -164,23 +169,35 @@ return {
|
|||||||
},
|
},
|
||||||
["app-claw"] = {
|
["app-claw"] = {
|
||||||
desc = "KittenOS NEO Package Manager",
|
desc = "KittenOS NEO Package Manager",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo"
|
"neo"
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
||||||
"apps",
|
"apps"
|
||||||
"libs"
|
|
||||||
},
|
},
|
||||||
files = {
|
files = {
|
||||||
"apps/app-claw.lua",
|
"apps/app-claw.lua",
|
||||||
"libs/app-claw-core.lua",
|
"apps/svc-app-claw-worker.lua"
|
||||||
"libs/app-claw-csi.lua"
|
},
|
||||||
|
},
|
||||||
|
["svc-t"] = {
|
||||||
|
desc = "KittenOS NEO Terminal System",
|
||||||
|
v = 10,
|
||||||
|
deps = {
|
||||||
|
"neo"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/svc-t.lua",
|
||||||
|
"apps/app-luashell.lua"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
["neo-meta"] = {
|
["neo-meta"] = {
|
||||||
desc = "KittenOS NEO: Use 'All' to install to other disks",
|
desc = "KittenOS NEO: Use 'All' to install to other disks",
|
||||||
v = 2,
|
v = 10,
|
||||||
deps = {
|
deps = {
|
||||||
"neo",
|
"neo",
|
||||||
"neo-init",
|
"neo-init",
|
||||||
@ -189,9 +206,11 @@ return {
|
|||||||
"neo-icecap",
|
"neo-icecap",
|
||||||
"neo-secpolicy",
|
"neo-secpolicy",
|
||||||
"neo-coreapps",
|
"neo-coreapps",
|
||||||
"app-klogo",
|
"neo-logo",
|
||||||
|
"app-bmpview",
|
||||||
"app-flash",
|
"app-flash",
|
||||||
"app-claw",
|
"app-claw",
|
||||||
|
"svc-t",
|
||||||
"app-wget"
|
"app-wget"
|
||||||
},
|
},
|
||||||
dirs = {
|
dirs = {
|
328
claw/repo-claw.lua
Normal file
328
claw/repo-claw.lua
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- local.lua : CLAW Repository Metadata
|
||||||
|
-- Authors: 20kdc
|
||||||
|
|
||||||
|
return {
|
||||||
|
["app-eeprog"] = {
|
||||||
|
desc = "Example program: EEPROM programmer / copier",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-eeprog.lua",
|
||||||
|
"docs/repoauthors/app-eeprog"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["neo-docs"] = {
|
||||||
|
desc = "KittenOS NEO system documentation",
|
||||||
|
v = 10,
|
||||||
|
deps = {
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"docs/an-intro",
|
||||||
|
"docs/kn-intro",
|
||||||
|
"docs/kn-refer",
|
||||||
|
"docs/kn-sched",
|
||||||
|
"docs/kn-perms",
|
||||||
|
"docs/us-perms",
|
||||||
|
"docs/us-nxapp",
|
||||||
|
"docs/us-setti",
|
||||||
|
"docs/us-evrst",
|
||||||
|
"docs/us-clawf",
|
||||||
|
"docs/us-termi",
|
||||||
|
"docs/ul-seria",
|
||||||
|
"docs/ul-fwrap",
|
||||||
|
"docs/ul-event",
|
||||||
|
"docs/ul-fmttx",
|
||||||
|
"docs/ul-neoux",
|
||||||
|
"docs/ul-brail",
|
||||||
|
"docs/ul-bmp__",
|
||||||
|
"docs/ul-linee",
|
||||||
|
"docs/gp-pedan",
|
||||||
|
"docs/repoauthors/neo-docs"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-nbox2018"] = {
|
||||||
|
desc = "NBOX2018 and NPRT2018, a 3D-printing toolbox",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-nbox2018.lua",
|
||||||
|
"apps/app-nprt2018.lua",
|
||||||
|
"docs/repoauthors/app-nbox2018"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-allmem"] = {
|
||||||
|
desc = "Near-reproducible memory usage figures",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-allmem.lua",
|
||||||
|
"docs/repoauthors/app-allmem"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-telnet"] = {
|
||||||
|
desc = "TELNET client",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"svc-t",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-telnet.lua",
|
||||||
|
"docs/repoauthors/app-telnet"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["svc-ghostie"] = {
|
||||||
|
desc = "Application that schedules a scare after a random time to test svc autostart",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/svc-ghostie.lua",
|
||||||
|
"apps/app-ghostcall.lua",
|
||||||
|
"docs/repoauthors/svc-ghostie"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-metamachine"] = {
|
||||||
|
desc = "Virtual machine",
|
||||||
|
v = 5,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"libs",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors",
|
||||||
|
"data",
|
||||||
|
"data/app-metamachine"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-metamachine.lua",
|
||||||
|
"libs/metamachine-vgpu.lua",
|
||||||
|
"libs/metamachine-vfs.lua",
|
||||||
|
"docs/repoauthors/app-metamachine",
|
||||||
|
"data/app-metamachine/confboot.lua",
|
||||||
|
"data/app-metamachine/lucaboot.lua"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-pclogix-upload"] = {
|
||||||
|
desc = "paste.pc-logix.com text uploader",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-pclogix-upload.lua",
|
||||||
|
"docs/repoauthors/app-pclogix-upload"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-rsctrl"] = {
|
||||||
|
desc = "Redstone control",
|
||||||
|
v = 1,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-rsctrl.lua",
|
||||||
|
"docs/repoauthors/app-rsctrl"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-nbcompose"] = {
|
||||||
|
desc = "Music player/composer using the NBS format",
|
||||||
|
v = 2,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"lib-knbs",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-nbcompose.lua",
|
||||||
|
"docs/repoauthors/app-nbcompose"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-tapedeck"] = {
|
||||||
|
desc = "Computronics Tape Drive interface",
|
||||||
|
v = 3,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-tapedeck.lua",
|
||||||
|
"docs/repoauthors/app-tapedeck"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-launchbar"] = {
|
||||||
|
desc = "Application launcher bar",
|
||||||
|
v = 0,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-pd"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-launchbar.lua",
|
||||||
|
"docs/repoauthors/app-launchbar"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["app-slaunch"] = {
|
||||||
|
desc = "Searching launcher",
|
||||||
|
v = 0,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-pd"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-slaunch.lua",
|
||||||
|
"docs/repoauthors/app-slaunch"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- libraries
|
||||||
|
["lib-knbs"] = {
|
||||||
|
desc = "NBS reader/writer library",
|
||||||
|
v = 2,
|
||||||
|
deps = {
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"libs",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"libs/knbs.lua",
|
||||||
|
"docs/repoauthors/lib-knbs"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["svc-virtudev"] = {
|
||||||
|
desc = "a clone of vcomponent",
|
||||||
|
v = 2,
|
||||||
|
deps = {
|
||||||
|
"neo",
|
||||||
|
"zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"docs",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/svc-virtudev.lua",
|
||||||
|
"apps/app-vdrslamp.lua",
|
||||||
|
"docs/us-virtu",
|
||||||
|
"docs/repoauthors/svc-virtudev"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- licenses (MUST BE IMMUTABLE)
|
||||||
|
["zzz-license-pd"] = {
|
||||||
|
desc = "license file 'Public Domain'",
|
||||||
|
v = 0,
|
||||||
|
deps = {
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"docs",
|
||||||
|
"docs/licensing",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"docs/licensing/Public Domain",
|
||||||
|
"docs/repoauthors/zzz-license-pd"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["zzz-license-kosneo-bsd0"] = {
|
||||||
|
desc = "license file 'KittenOS NEO BSD0'",
|
||||||
|
v = 0,
|
||||||
|
deps = {
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"docs",
|
||||||
|
"docs/licensing",
|
||||||
|
"docs/repoauthors"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"docs/licensing/KittenOS NEO BSD0",
|
||||||
|
"docs/repoauthors/zzz-license-kosneo-bsd0"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
local merges = {...}
|
|
||||||
neo = {
|
|
||||||
wrapMeta = function (x)
|
|
||||||
return x
|
|
||||||
end
|
|
||||||
}
|
|
||||||
local serial = loadfile("code/libs/serial.lua")()
|
|
||||||
local repo = {}
|
|
||||||
for _, v in ipairs(merges) do
|
|
||||||
local f = io.open(v, "rb")
|
|
||||||
local fd = f:read("*a")
|
|
||||||
f:close()
|
|
||||||
for k, v in pairs(serial.deserialize(fd)) do
|
|
||||||
repo[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
io.write(serial.serialize(repo))
|
|
78
code/apps/app-batmon.lua
Normal file
78
code/apps/app-batmon.lua
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- app-batmon: Still not batman.
|
||||||
|
-- Port of the original 'batmon.lua' from KittenOS Legacy.
|
||||||
|
local window = neo.requireAccess("x.neo.pub.window", "window")(10, 2)
|
||||||
|
|
||||||
|
-- OCE/s, OCE at last check, uptime of last timer set, uptime of last check
|
||||||
|
local lastChange, lastValue, lastTimer, lpTimer = 0
|
||||||
|
local usage = {
|
||||||
|
"[####]:",
|
||||||
|
"[###:]:",
|
||||||
|
"[### ]:",
|
||||||
|
"[##: ]:",
|
||||||
|
"[## ]:",
|
||||||
|
"[#: ]:",
|
||||||
|
"[# ]:",
|
||||||
|
"[: ]:",
|
||||||
|
"[ ]:",
|
||||||
|
"WARNING"
|
||||||
|
}
|
||||||
|
local function getText(y)
|
||||||
|
if y == 2 then
|
||||||
|
if not lastChange then
|
||||||
|
return "Wait..."
|
||||||
|
end
|
||||||
|
local ind = "Dc. "
|
||||||
|
local wc = lastChange
|
||||||
|
local wv = os.energy()
|
||||||
|
if wc > 0 then
|
||||||
|
wc = -wc
|
||||||
|
wv = os.maxEnergy() - wv
|
||||||
|
ind = "Ch. "
|
||||||
|
end
|
||||||
|
local m = math.floor((wv / -wc) / 60)
|
||||||
|
return ind .. m .. "m"
|
||||||
|
end
|
||||||
|
local dec = os.energy() / os.maxEnergy()
|
||||||
|
-- dec is from 0 to 1.
|
||||||
|
local potential = math.floor(dec * #usage)
|
||||||
|
if potential < 0 then potential = 1 end
|
||||||
|
if potential >= #usage then potential = #usage - 1 end
|
||||||
|
return usage[#usage - potential]
|
||||||
|
end
|
||||||
|
local function update()
|
||||||
|
local nv = os.energy()
|
||||||
|
if lastValue then
|
||||||
|
lastChange = (nv - lastValue) / (os.uptime() - lpTimer)
|
||||||
|
end
|
||||||
|
lpTimer = os.uptime()
|
||||||
|
lastValue = nv
|
||||||
|
lastTimer = os.uptime() + 10
|
||||||
|
if lastChange then
|
||||||
|
if lastChange > 10 then
|
||||||
|
lastTimer = lastTimer - 9
|
||||||
|
end
|
||||||
|
end
|
||||||
|
neo.scheduleTimer(lastTimer)
|
||||||
|
window.setSize(10, 2)
|
||||||
|
end
|
||||||
|
update()
|
||||||
|
while true do
|
||||||
|
local ev, a, b, c = coroutine.yield()
|
||||||
|
if ev == "x.neo.pub.window" then
|
||||||
|
if b == "close" then
|
||||||
|
return
|
||||||
|
elseif b == "line" then
|
||||||
|
local tx = getText(c):sub(1, 10)
|
||||||
|
window.span(1, c, tx .. (" "):rep(10 - #tx), 0xFFFFFF, 0)
|
||||||
|
end
|
||||||
|
elseif ev == "k.timer" then
|
||||||
|
update()
|
||||||
|
end
|
||||||
|
end
|
@ -1,12 +1,15 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
local neoux = require("neoux")(event, neo)
|
local neoux = require("neoux")(event, neo)
|
||||||
local braille = require("braille")
|
local braille = require("braille")
|
||||||
local bmp = require("bmp")
|
local bmp = require("bmp")
|
||||||
local icecap = neo.requireAccess("x.neo.pub.base", "loadimg")
|
local file = neoux.fileDialog(false)
|
||||||
local file = icecap.open("/logo.bmp", false)
|
|
||||||
|
|
||||||
local header = file.read(bmp.headerMinSzBMP)
|
local header = file.read(bmp.headerMinSzBMP)
|
||||||
local palette = ""
|
local palette = ""
|
||||||
@ -61,9 +64,6 @@ lcWidth = bitmap.dsSpan
|
|||||||
local running = true
|
local running = true
|
||||||
|
|
||||||
local function decodeRGB(rgb, igp, col)
|
local function decodeRGB(rgb, igp, col)
|
||||||
if igp and bitmap.bpp > 24 then
|
|
||||||
rgb = math.floor(rgb / 256)
|
|
||||||
end
|
|
||||||
local r, g, b = math.floor(rgb / 65536) % 256, math.floor(rgb / 256) % 256, rgb % 256
|
local r, g, b = math.floor(rgb / 65536) % 256, math.floor(rgb / 256) % 256, rgb % 256
|
||||||
-- the new KittenOS NEO logo is 'sensitive' to dithering, so disable it
|
-- the new KittenOS NEO logo is 'sensitive' to dithering, so disable it
|
||||||
if not col then
|
if not col then
|
||||||
@ -82,6 +82,8 @@ local fp = neoux.tcwindow(bW, bH, {
|
|||||||
braille.new(1, 1, bW, bH, {
|
braille.new(1, 1, bW, bH, {
|
||||||
selectable = true,
|
selectable = true,
|
||||||
get = function (window, x, y, bg, fg, selected, colour)
|
get = function (window, x, y, bg, fg, selected, colour)
|
||||||
|
if x > bitmap.width then return 0, 0, 0 end
|
||||||
|
if y > bitmap.height then return 0, 0, 0 end
|
||||||
if bitmap.ignoresPalette then
|
if bitmap.ignoresPalette then
|
||||||
return decodeRGB(bitmap.getPixel(x - 1, y - 1, 0), true, colour)
|
return decodeRGB(bitmap.getPixel(x - 1, y - 1, 0), true, colour)
|
||||||
end
|
end
|
||||||
@ -95,9 +97,9 @@ end, 0xFFFFFF, 0)
|
|||||||
|
|
||||||
neoux.create(bW, bH, nil, function (w, t, r, ...)
|
neoux.create(bW, bH, nil, function (w, t, r, ...)
|
||||||
if t == "focus" then
|
if t == "focus" then
|
||||||
if r then
|
if r and not bitmap.ignoresPalette then
|
||||||
local pal = {}
|
local pal = {}
|
||||||
for i = 0, 15 do
|
for i = 0, math.min(15, bitmap.paletteCol - 1) do
|
||||||
pal[i + 1] = bitmap.getPalette(i)
|
pal[i + 1] = bitmap.getPalette(i)
|
||||||
end
|
end
|
||||||
w.recommendPalette(pal)
|
w.recommendPalette(pal)
|
@ -1,148 +1,84 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- app-claw: Package manager.
|
-- app-claw: Package manager.
|
||||||
|
|
||||||
|
local ldrPkg, _, tgtPkg = ...
|
||||||
|
|
||||||
-- libs & such
|
-- libs & such
|
||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
local neoux, err = require("neoux")
|
local neoux = require("neoux")(event, neo)
|
||||||
if not neoux then error(err) end
|
|
||||||
neoux = neoux(event, neo)
|
|
||||||
local claw = require("app-claw-core")()
|
|
||||||
local clawcsi = require("app-claw-csi")
|
|
||||||
|
|
||||||
local source = "http://20kdc.duckdns.org/neo/"
|
|
||||||
local disks = neo.requireAccess("c.filesystem", "searching disks for packages")
|
|
||||||
local primaryDisk = disks.primary
|
|
||||||
local primaryINet = neo.requestAccess("c.internet")
|
local primaryINet = neo.requestAccess("c.internet")
|
||||||
if primaryINet then primaryINet = primaryINet.list()() end
|
if primaryINet then primaryINet = primaryINet.list()() end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
local function yielder()
|
local function readFile(src, url, ocb)
|
||||||
-- slightly dangerous, but what can we do?
|
local buf = ""
|
||||||
pcall(event.sleepTo, os.uptime() + 0.05)
|
local function cb(data)
|
||||||
end
|
if not data then
|
||||||
|
ocb(buf)
|
||||||
local function download(url, cb)
|
|
||||||
if not primaryINet then return nil, "no internet" end
|
|
||||||
local req, err = primaryINet.request(source .. url)
|
|
||||||
if not req then
|
|
||||||
cb(nil)
|
|
||||||
return nil, "dlR/" .. tostring(err)
|
|
||||||
end
|
|
||||||
-- OpenComputers#535
|
|
||||||
req.finishConnect()
|
|
||||||
while true do
|
|
||||||
local n, n2 = req.read(neo.readBufSize)
|
|
||||||
local o, r = cb(n)
|
|
||||||
if not o then
|
|
||||||
req.close()
|
|
||||||
return nil, r
|
|
||||||
end
|
|
||||||
if not n then
|
|
||||||
req.close()
|
|
||||||
if n2 then
|
|
||||||
return nil, n2
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
if n == "" then
|
buf = buf .. data
|
||||||
yielder()
|
buf = buf:gsub("[^\n]*\n", function (t)
|
||||||
end
|
ocb(t:sub(1, -2))
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
if type(src) == "string" then
|
||||||
end
|
assert(primaryINet, "no internet")
|
||||||
|
local req, err = primaryINet.request(src .. url)
|
||||||
local function fsSrc(disk)
|
assert(req, err)
|
||||||
return function (url, cb)
|
-- OpenComputers#535
|
||||||
local h, e = disk.open(url, "rb")
|
req.finishConnect()
|
||||||
if not h then cb(nil) return nil, tostring(e) end
|
while true do
|
||||||
local c = ""
|
local n, n2 = req.read(neo.readBufSize)
|
||||||
while c do
|
cb(n)
|
||||||
c = disk.read(h, neo.readBufSize)
|
if not n then
|
||||||
local o, r = cb(c)
|
req.close()
|
||||||
if not o then return nil, r end
|
if n2 then
|
||||||
end
|
error(n2)
|
||||||
disk.close(h)
|
else
|
||||||
return true
|
cb(nil)
|
||||||
end
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fsDst(disk)
|
|
||||||
return {function (url)
|
|
||||||
local h, e = disk.open(url, "wb")
|
|
||||||
if not h then return nil, tostring(e) end
|
|
||||||
return function (d)
|
|
||||||
local ok, r = true
|
|
||||||
if d then
|
|
||||||
ok, r = disk.write(h, d)
|
|
||||||
else
|
else
|
||||||
disk.close(h)
|
if n == "" then
|
||||||
|
-- slightly dangerous, but what can we do?
|
||||||
|
pcall(event.sleepTo, os.uptime() + 0.05)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if not ok then return nil, tostring(r) end
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end, disk.makeDirectory, disk.exists, disk.isDirectory, disk.remove, disk.rename}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function checked(...)
|
|
||||||
local res, res2, err = pcall(...)
|
|
||||||
if not res then
|
|
||||||
neoux.startDialog(tostring(res2), "error!", true)
|
|
||||||
elseif not res2 then
|
|
||||||
neoux.startDialog(tostring(err), "failed!", true)
|
|
||||||
else
|
else
|
||||||
return res2
|
if url == "data/app-claw/local.c2l" then
|
||||||
|
for _, v in ipairs(src.list("data/app-claw/")) do
|
||||||
|
ocb(v)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local h, e = src.open(url, "rb")
|
||||||
|
assert(h, e)
|
||||||
|
repeat
|
||||||
|
local c = src.read(h, neo.readBufSize)
|
||||||
|
cb(c)
|
||||||
|
until not c
|
||||||
|
src.close(h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Beginning Of The App (well, the actual one)
|
-- Sources
|
||||||
|
|
||||||
local genCurrent, genPrimary, genPackage, primaryWindow
|
|
||||||
local running = true
|
|
||||||
|
|
||||||
-- primary
|
|
||||||
local primarySearchTx = ""
|
|
||||||
local primaryPage = 1
|
|
||||||
local primaryList = {}
|
|
||||||
local primaryNextMinus = false
|
|
||||||
|
|
||||||
-- package
|
|
||||||
local packageLock = nil
|
|
||||||
local packageId = "FIXME"
|
|
||||||
|
|
||||||
|
|
||||||
local function describe(pkg)
|
|
||||||
local weHave = claw.getInfo(pkg, "local")
|
|
||||||
local theyHave = claw.getInfo(pkg, "local")
|
|
||||||
local someoneHas = claw.getInfo(pkg, nil, true)
|
|
||||||
if weHave then
|
|
||||||
if theyHave.v > weHave.v then
|
|
||||||
return pkg .. " [v" .. weHave.v .. "!]"
|
|
||||||
end
|
|
||||||
if someoneHas.v < weHave.v then
|
|
||||||
return pkg .. " (v" .. weHave.v .. ") R<"
|
|
||||||
end
|
|
||||||
return pkg .. " (v" .. weHave.v .. ")"
|
|
||||||
end
|
|
||||||
return pkg
|
|
||||||
end
|
|
||||||
|
|
||||||
local function primaryWindowRegenCore()
|
|
||||||
local gen, gens = genCurrent()
|
|
||||||
return 25, 12, "claw", neoux.tcwindow(25, 12, gen, function (w)
|
|
||||||
w.close()
|
|
||||||
running = false
|
|
||||||
end, 0xFF8F00, 0, gens)
|
|
||||||
end
|
|
||||||
local function primaryWindowRegen()
|
|
||||||
primaryWindow.reset(primaryWindowRegenCore())
|
|
||||||
end
|
|
||||||
|
|
||||||
|
local sources = {}
|
||||||
|
local sourceList = {}
|
||||||
-- Use all non-primary filesystems
|
-- Use all non-primary filesystems
|
||||||
|
local disks = neo.requireAccess("c.filesystem", "searching disks for packages")
|
||||||
|
local primaryDisk = disks.primary
|
||||||
for pass = 1, 3 do
|
for pass = 1, 3 do
|
||||||
for v in disks.list() do
|
for v in disks.list() do
|
||||||
local nam = nil
|
local nam = nil
|
||||||
@ -154,11 +90,8 @@ for pass = 1, 3 do
|
|||||||
nam = v.address
|
nam = v.address
|
||||||
end
|
end
|
||||||
if nam then
|
if nam then
|
||||||
local ok, r = clawcsi(claw, nam, fsSrc(v), (not v.isReadOnly()) and fsDst(v))
|
sources[nam] = v
|
||||||
if not ok and nam == "local" then
|
table.insert(sourceList, nam)
|
||||||
claw.unlock()
|
|
||||||
error(r)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -167,19 +100,105 @@ end
|
|||||||
disks = nil
|
disks = nil
|
||||||
|
|
||||||
if primaryINet then
|
if primaryINet then
|
||||||
checked(clawcsi, claw, "inet", download)
|
sources["inet"] = "http://20kdc.duckdns.org/neo/"
|
||||||
|
table.insert(sourceList, "inet")
|
||||||
end
|
end
|
||||||
|
|
||||||
clawcsi = nil
|
-- List scanning for package window
|
||||||
|
|
||||||
primaryList = claw.getList()
|
local function scanList(content)
|
||||||
|
local lst = {}
|
||||||
|
local lst2 = {}
|
||||||
|
for k, v in pairs(sources) do
|
||||||
|
local ok, err = pcall(readFile, v, "data/app-claw/local.c2l", function (l)
|
||||||
|
if l:sub(-4) == ".c2p" then
|
||||||
|
local lt, ltv = l:sub(1, -5)
|
||||||
|
ltv = lt:match("%.[0-9]+$")
|
||||||
|
if ltv and l:find(content, 1, true) then
|
||||||
|
lt = lt:sub(1, -(#ltv + 1))
|
||||||
|
lst2[lt] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
if (not ok) and ((k == "inet") or (k == "local")) then
|
||||||
|
neoux.startDialog(tostring(err), k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k, v in pairs(lst2) do
|
||||||
|
table.insert(lst, k)
|
||||||
|
end
|
||||||
|
table.sort(lst)
|
||||||
|
return lst
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Beginning Of The App (well, the actual one)
|
||||||
|
|
||||||
|
local genCurrent, genPrimary, genPackage, primaryWindow
|
||||||
|
local running = true
|
||||||
|
|
||||||
|
-- primary
|
||||||
|
local primarySearchTx = ""
|
||||||
|
local primaryPage = 1
|
||||||
|
local primaryList = scanList("")
|
||||||
|
local primaryNextMinus = false
|
||||||
|
|
||||||
|
-- package
|
||||||
|
local packageLock = nil
|
||||||
|
local packageId = "FIXME"
|
||||||
|
|
||||||
|
local function describe(pkgs)
|
||||||
|
local lowestV, highestV, myV = {}, {}, {}
|
||||||
|
for pk, pv in ipairs(pkgs) do
|
||||||
|
lowestV[pk] = math.huge
|
||||||
|
highestV[pk] = -math.huge
|
||||||
|
end
|
||||||
|
for k, v in pairs(sources) do
|
||||||
|
pcall(readFile, v, "data/app-claw/local.c2l", function (l)
|
||||||
|
local lp = l:match("%.[0-9]+%.c2p$")
|
||||||
|
for pk, pkg in ipairs(pkgs) do
|
||||||
|
if lp and l:sub(1, -(#lp + 1)) == pkg then
|
||||||
|
local v = tonumber(lp:sub(2, -5))
|
||||||
|
if k == "local" then
|
||||||
|
myV[pk] = v
|
||||||
|
end
|
||||||
|
lowestV[pk] = math.min(lowestV[pk], v)
|
||||||
|
highestV[pk] = math.max(highestV[pk], v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
for pk, pkg in ipairs(pkgs) do
|
||||||
|
if lowestV[pk] == math.huge then
|
||||||
|
pkgs[pk] = pkg .. " (ERR)"
|
||||||
|
elseif myV[pk] then
|
||||||
|
if highestV[pk] > myV[pk] then
|
||||||
|
pkgs[pk] = pkg .. " [v" .. myV[pk] .. "!]"
|
||||||
|
elseif lowestV[pk] < myV[pk] then
|
||||||
|
pkgs[pk] = pkg .. " (v" .. myV[pk] .. ") R<"
|
||||||
|
else
|
||||||
|
pkgs[pk] = pkg .. " (v" .. myV[pk] .. ")"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function primaryWindowRegenCore()
|
||||||
|
local gen, gens = genCurrent()
|
||||||
|
return 25, 14, "claw", neoux.tcwindow(25, 14, gen, function (w)
|
||||||
|
w.close()
|
||||||
|
running = false
|
||||||
|
end, 0xFF8F00, 0, gens)
|
||||||
|
end
|
||||||
|
local function primaryWindowRegen()
|
||||||
|
primaryWindow.reset(primaryWindowRegenCore())
|
||||||
|
end
|
||||||
|
|
||||||
-- Sections
|
-- Sections
|
||||||
|
|
||||||
function genPrimary()
|
function genPrimary()
|
||||||
local minus = (primaryNextMinus and 3) or nil
|
local minus = (primaryNextMinus and 3) or nil
|
||||||
primaryNextMinus = false
|
primaryNextMinus = false
|
||||||
local pgs = 10
|
local pgs = 12
|
||||||
local pages = math.ceil(#primaryList / pgs)
|
local pages = math.ceil(#primaryList / pgs)
|
||||||
local elems = {
|
local elems = {
|
||||||
neoux.tcbutton(23, 1, "+", function (w)
|
neoux.tcbutton(23, 1, "+", function (w)
|
||||||
@ -198,14 +217,22 @@ function genPrimary()
|
|||||||
end)
|
end)
|
||||||
}
|
}
|
||||||
local base = (primaryPage - 1) * pgs
|
local base = (primaryPage - 1) * pgs
|
||||||
|
local pkgs = {}
|
||||||
for i = 1, pgs do
|
for i = 1, pgs do
|
||||||
local ent = primaryList[base + i]
|
local ent = primaryList[base + i]
|
||||||
if ent then
|
if ent then
|
||||||
local enttx = describe(ent)
|
pkgs[i] = ent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
describe(pkgs)
|
||||||
|
for i = 1, pgs do
|
||||||
|
local ent = primaryList[base + i]
|
||||||
|
if ent then
|
||||||
|
local enttx = pkgs[i]
|
||||||
table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w)
|
table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w)
|
||||||
-- FREE UP MEMORY NOW
|
-- FREE UP MEMORY NOW
|
||||||
elems = {}
|
elems = {}
|
||||||
w.reset(25, 12, "claw", function (ev)
|
w.reset(25, 14, "claw", function (ev)
|
||||||
if ev == "close" then
|
if ev == "close" then
|
||||||
w.close()
|
w.close()
|
||||||
running = false
|
running = false
|
||||||
@ -217,22 +244,13 @@ function genPrimary()
|
|||||||
end))
|
end))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(elems, neoux.tcfield(1, 12, 16, function (s)
|
table.insert(elems, neoux.tcfield(1, 14, 16, function (s)
|
||||||
if s then primarySearchTx = s end
|
if s then primarySearchTx = s end
|
||||||
return primarySearchTx
|
return primarySearchTx
|
||||||
end))
|
end))
|
||||||
table.insert(elems, neoux.tcbutton(17, 12, "Search!", function (w)
|
table.insert(elems, neoux.tcbutton(17, 14, "Search!", function (w)
|
||||||
local n = {}
|
|
||||||
for _, v in ipairs(claw.getList()) do
|
|
||||||
for i = 1, #v do
|
|
||||||
if v:sub(i, i + #primarySearchTx - 1) == primarySearchTx then
|
|
||||||
table.insert(n, v)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
primaryPage = 1
|
primaryPage = 1
|
||||||
primaryList = n
|
primaryList = scanList(primarySearchTx)
|
||||||
primaryWindowRegen()
|
primaryWindowRegen()
|
||||||
end))
|
end))
|
||||||
return elems, minus
|
return elems, minus
|
||||||
@ -245,49 +263,38 @@ local function packageGetBB(src, lclI, srcI, srcW)
|
|||||||
if srcI and srcW then
|
if srcI and srcW then
|
||||||
table.insert(buttons, {
|
table.insert(buttons, {
|
||||||
"Del",
|
"Del",
|
||||||
function ()
|
function (w)
|
||||||
if packageLock then return end
|
w.close()
|
||||||
packageLock = ""
|
running = false
|
||||||
checked(claw.remove, src, packageId, true)
|
neo.executeAsync("svc-app-claw-worker", sources[src], packageId, nil, src == "local", primaryINet)
|
||||||
packageLock = nil
|
|
||||||
primaryWindowRegen()
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
if srcI and ((not lclI) or (lclI.v < srcI.v)) then
|
if srcI and ((not lclI) or (lclI < srcI)) then
|
||||||
table.insert(buttons, {
|
table.insert(buttons, {
|
||||||
"Get",
|
"Get",
|
||||||
function ()
|
function (w)
|
||||||
if packageLock then return end
|
w.close()
|
||||||
packageLock = "installing from " .. src
|
running = false
|
||||||
primaryWindowRegen()
|
neo.executeAsync("svc-app-claw-worker", sources["local"], packageId, sources[src], true, primaryINet)
|
||||||
checked(claw.installTo, "local", packageId, src, true, yielder)
|
|
||||||
packageLock = nil
|
|
||||||
primaryWindowRegen()
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
if srcW and lclI and not srcI then
|
if srcW and lclI and not srcI then
|
||||||
table.insert(buttons, {
|
table.insert(buttons, {
|
||||||
"All",
|
"All",
|
||||||
function ()
|
function (w)
|
||||||
if packageLock then return end
|
w.close()
|
||||||
packageLock = "storing w/ dependencies at " .. src
|
running = false
|
||||||
primaryWindowRegen()
|
neo.executeAsync("svc-app-claw-worker", sources[src], packageId, sources["local"], true, primaryINet)
|
||||||
checked(claw.installTo, src, packageId, "local", true, yielder)
|
|
||||||
packageLock = nil
|
|
||||||
primaryWindowRegen()
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
table.insert(buttons, {
|
table.insert(buttons, {
|
||||||
"Put",
|
"Put",
|
||||||
function ()
|
function (w)
|
||||||
if packageLock then return end
|
w.close()
|
||||||
packageLock = "storing at " .. src
|
running = false
|
||||||
primaryWindowRegen()
|
neo.executeAsync("svc-app-claw-worker", sources[src], packageId, sources["local"], false, primaryINet)
|
||||||
checked(claw.installTo, src, packageId, "local", false, yielder)
|
|
||||||
packageLock = nil
|
|
||||||
primaryWindowRegen()
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -306,26 +313,50 @@ function genPackage()
|
|||||||
-- inet v21 <pull>
|
-- inet v21 <pull>
|
||||||
-- dir v22 <pull> <push>
|
-- dir v22 <pull> <push>
|
||||||
-- crockett <push>
|
-- crockett <push>
|
||||||
local info = claw.getInfo(packageId)
|
local sourceVers = {}
|
||||||
local infoL = claw.getInfo(packageId, "local")
|
local c2pSrc = "local"
|
||||||
|
local c2pVer = -1
|
||||||
|
for k, v in pairs(sources) do
|
||||||
|
local ok, err = pcall(readFile, v, "data/app-claw/local.c2l", function (l)
|
||||||
|
local lp = l:match("%.[0-9]+%.c2p$")
|
||||||
|
if lp and l:sub(1, -(#lp + 1)) == packageId then
|
||||||
|
sourceVers[k] = tonumber(lp:sub(2, -5))
|
||||||
|
if c2pVer < sourceVers[k] then
|
||||||
|
c2pSrc = k
|
||||||
|
c2pVer = sourceVers[k]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if sourceVers["local"] then
|
||||||
|
c2pSrc = "local"
|
||||||
|
c2pVer = sourceVers["local"]
|
||||||
|
end
|
||||||
|
local text = ""
|
||||||
|
local ok = pcall(readFile, sources[c2pSrc], "data/app-claw/" .. packageId .. "." .. c2pVer .. ".c2p", function (l)
|
||||||
|
text = text .. l .. "\n"
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
text = packageId .. "\nUnable to read v" .. c2pVer .. " c2p from: " .. c2pSrc
|
||||||
|
end
|
||||||
local elems = {
|
local elems = {
|
||||||
neoux.tcrawview(1, 1, neoux.fmtText(unicode.safeTextFormat(packageId .. "\n" .. info.desc .. "\nv" .. info.v .. " deps " .. table.concat(info.deps, ", ")), 25)),
|
neoux.tcrawview(1, 1, neoux.fmtText(unicode.safeTextFormat(text), 25)),
|
||||||
neoux.tcbutton(20, 1, "Back", function ()
|
neoux.tcbutton(20, 1, "Back", function ()
|
||||||
if packageLock then return end
|
if packageLock then return end
|
||||||
genCurrent = genPrimary
|
genCurrent = genPrimary
|
||||||
primaryWindowRegen()
|
primaryWindowRegen()
|
||||||
end)
|
end)
|
||||||
}
|
}
|
||||||
for k, v in ipairs(claw.sourceList) do
|
for k, v in ipairs(sourceList) do
|
||||||
local lI = claw.getInfo(packageId, v[1])
|
local row = 14 + k - #sourceList
|
||||||
local row = 12 + k - #(claw.sourceList)
|
|
||||||
local pfx = " "
|
local pfx = " "
|
||||||
if lI then
|
if sourceVers[v] then
|
||||||
pfx = "v" .. string.format("%04i", lI.v) .. " "
|
pfx = "v" .. string.format("%04i", sourceVers[v]) .. " "
|
||||||
end
|
end
|
||||||
table.insert(elems, neoux.tcrawview(1, row, {neoux.pad(pfx .. v[1], 14, false, true)}))
|
table.insert(elems, neoux.tcrawview(1, row, {neoux.pad(pfx .. v, 14, false, true)}))
|
||||||
local col = 26
|
local col = 26
|
||||||
for _, bv in ipairs(packageGetBB(v[1], infoL, lI, v[2])) do
|
local srcW = type(sources[v]) ~= "string"
|
||||||
|
for _, bv in ipairs(packageGetBB(v, sourceVers["local"], sourceVers[v], srcW)) do
|
||||||
local b = neoux.tcbutton(col, row, bv[1], bv[2])
|
local b = neoux.tcbutton(col, row, bv[1], bv[2])
|
||||||
col = col - b.w
|
col = col - b.w
|
||||||
b.x = col
|
b.x = col
|
||||||
@ -337,10 +368,14 @@ end
|
|||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
genCurrent = genPrimary
|
if ldrPkg == "svc-app-claw-worker" and tgtPkg then
|
||||||
|
packageId = tgtPkg
|
||||||
|
genCurrent = genPackage
|
||||||
|
else
|
||||||
|
genCurrent = genPrimary
|
||||||
|
end
|
||||||
primaryWindow = neoux.create(primaryWindowRegenCore())
|
primaryWindow = neoux.create(primaryWindowRegenCore())
|
||||||
|
|
||||||
while running do
|
while running do
|
||||||
event.pull()
|
event.pull()
|
||||||
end
|
end
|
||||||
claw.unlock()
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- app-control: Settings changer
|
-- app-control: Settings changer
|
||||||
local settings = neo.requireAccess("x.neo.sys.manage", "management")
|
local settings = neo.requireAccess("x.neo.sys.manage", "management")
|
||||||
@ -226,7 +230,7 @@ window = neoux.create(currentGen())
|
|||||||
while running do
|
while running do
|
||||||
local src, id, k, v = event.pull()
|
local src, id, k, v = event.pull()
|
||||||
if src == "x.neo.sys.manage" then
|
if src == "x.neo.sys.manage" then
|
||||||
if id == "set_setting" then
|
if id == "set_setting" and currentGen ~= logGen then
|
||||||
window.reset(currentGen())
|
window.reset(currentGen())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
local neoux = require("neoux")(event, neo)
|
local neoux = require("neoux")(event, neo)
|
||||||
@ -20,12 +24,14 @@ local busy = false
|
|||||||
local regenCore
|
local regenCore
|
||||||
|
|
||||||
local function regenLabeller(set, get, wd)
|
local function regenLabeller(set, get, wd)
|
||||||
|
local tx = get()
|
||||||
return wd, 2, nil, neoux.tcwindow(wd, 1, {
|
return wd, 2, nil, neoux.tcwindow(wd, 1, {
|
||||||
neoux.tcfield(1, 1, wd, function (nt)
|
neoux.tcfield(1, 1, wd, function (nt)
|
||||||
if nt then
|
if nt then
|
||||||
|
tx = nt
|
||||||
set(nt)
|
set(nt)
|
||||||
end
|
end
|
||||||
return get()
|
return tx
|
||||||
end)
|
end)
|
||||||
}, function (w)
|
}, function (w)
|
||||||
busy = false
|
busy = false
|
||||||
@ -39,7 +45,7 @@ function regenCore()
|
|||||||
for v in eeprom.list() do
|
for v in eeprom.list() do
|
||||||
local lbl = unicode.safeTextFormat(v.getLabel())
|
local lbl = unicode.safeTextFormat(v.getLabel())
|
||||||
table.insert(elems, neoux.tcrawview(1, l, {
|
table.insert(elems, neoux.tcrawview(1, l, {
|
||||||
v.address:sub(1, 8) .. " " .. lbl
|
require("fmttext").pad(v.address:sub(1, 8) .. " " .. lbl, 25, false, true)
|
||||||
}))
|
}))
|
||||||
table.insert(elems, neoux.tcbutton(1, l + 1, "get", function (window)
|
table.insert(elems, neoux.tcbutton(1, l + 1, "get", function (window)
|
||||||
if busy then return end
|
if busy then return end
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- app-fm: dummy app to start FM
|
-- app-fm: dummy app to start FM
|
||||||
neo.requestAccess("x.neo.pub.base").showFileDialogAsync(nil)
|
neo.requestAccess("x.neo.pub.base").showFileDialogAsync(nil)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- app-launcher: The launcher
|
-- app-launcher: The launcher
|
||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
|
168
code/apps/app-luashell.lua
Normal file
168
code/apps/app-luashell.lua
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
local _, _, termId = ...
|
||||||
|
local ok = pcall(function ()
|
||||||
|
assert(string.sub(termId, 1, 12) == "x.neo.pub.t/")
|
||||||
|
end)
|
||||||
|
|
||||||
|
local termClose
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
termId = nil
|
||||||
|
assert(neo.executeAsync("svc-t", function (res)
|
||||||
|
termId = res.access
|
||||||
|
termClose = res.close
|
||||||
|
neo.scheduleTimer(0)
|
||||||
|
end, "luashell"))
|
||||||
|
while not termId do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
TERM = neo.requireAccess(termId, "terminal")
|
||||||
|
|
||||||
|
-- Using event makes it easier for stuff
|
||||||
|
-- within the shell to not spectacularly explode.
|
||||||
|
event = require("event")(neo)
|
||||||
|
|
||||||
|
local alive = true
|
||||||
|
event.listen("k.procdie", function (_, _, pid)
|
||||||
|
if pid == TERM.pid then
|
||||||
|
alive = false
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
TERM.write([[
|
||||||
|
KittenOS NEO Shell Usage Notes
|
||||||
|
|
||||||
|
Prefixing = is an alias for 'return '.
|
||||||
|
io.read(): Reads a line.
|
||||||
|
print: 'print with table dumping' impl.
|
||||||
|
TERM: Your terminal. (see us-termi doc.)
|
||||||
|
os.execute(): launch terminal apps!
|
||||||
|
tries '*', 'sys-t-*', 'svc-t-*', 'app-*'
|
||||||
|
example: os.execute("luashell")
|
||||||
|
os.exit(): quit the shell
|
||||||
|
=listCmdApps(): -t- (terminal) apps
|
||||||
|
event: useful for setting up listeners
|
||||||
|
without breaking shell functionality
|
||||||
|
]])
|
||||||
|
|
||||||
|
function listCmdApps()
|
||||||
|
local apps = {}
|
||||||
|
for _, v in ipairs(neo.listApps()) do
|
||||||
|
if v:sub(4, 6) == "-t-" then
|
||||||
|
table.insert(apps, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return apps
|
||||||
|
end
|
||||||
|
|
||||||
|
local function vPrint(slike, ...)
|
||||||
|
local s = {...}
|
||||||
|
if #s > 1 then
|
||||||
|
for i = 1, #s do
|
||||||
|
if i ~= 1 then TERM.write("\t") end
|
||||||
|
vPrint(slike, s[i])
|
||||||
|
end
|
||||||
|
elseif slike and type(s[1]) == "string" then
|
||||||
|
TERM.write("\"" .. s[1] .. "\"")
|
||||||
|
elseif type(s[1]) ~= "table" then
|
||||||
|
TERM.write(tostring(s[1]))
|
||||||
|
else
|
||||||
|
TERM.write("{")
|
||||||
|
for k, v in pairs(s[1]) do
|
||||||
|
TERM.write("[")
|
||||||
|
vPrint(true, k)
|
||||||
|
TERM.write("] = ")
|
||||||
|
vPrint(true, v)
|
||||||
|
TERM.write(", ")
|
||||||
|
end
|
||||||
|
TERM.write("}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print = function (...)
|
||||||
|
vPrint(false, ...)
|
||||||
|
TERM.write("\r\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
local ioBuffer = ""
|
||||||
|
|
||||||
|
io = {
|
||||||
|
read = function ()
|
||||||
|
while alive do
|
||||||
|
local pos = ioBuffer:find("\n")
|
||||||
|
if pos then
|
||||||
|
local line = ioBuffer:sub(1, pos):gsub("\r", "")
|
||||||
|
ioBuffer = ioBuffer:sub(pos + 1)
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
local e = {event.pull()}
|
||||||
|
if e[1] == TERM.id then
|
||||||
|
if e[2] == "data" then
|
||||||
|
ioBuffer = ioBuffer .. e[3]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
write = function (s) TERM.write(s) end
|
||||||
|
}
|
||||||
|
|
||||||
|
local originalOS = os
|
||||||
|
os = setmetatable({}, {
|
||||||
|
__index = originalOS
|
||||||
|
})
|
||||||
|
|
||||||
|
function os.exit()
|
||||||
|
alive = false
|
||||||
|
end
|
||||||
|
|
||||||
|
function os.execute(x, ...)
|
||||||
|
local subPid = neo.executeAsync(x, TERM.id, ...)
|
||||||
|
if not subPid then
|
||||||
|
subPid = neo.executeAsync("sys-t-" .. x, TERM.id, ...)
|
||||||
|
end
|
||||||
|
if not subPid then
|
||||||
|
subPid = neo.executeAsync("svc-t-" .. x, TERM.id, ...)
|
||||||
|
end
|
||||||
|
if not subPid then
|
||||||
|
subPid = neo.executeAsync("app-" .. x, TERM.id, ...)
|
||||||
|
end
|
||||||
|
if not subPid then
|
||||||
|
error("cannot find " .. x)
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
local e = {event.pull()}
|
||||||
|
if e[1] == "k.procdie" then
|
||||||
|
if e[3] == subPid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while alive do
|
||||||
|
TERM.write("> ")
|
||||||
|
local code = io.read()
|
||||||
|
if code then
|
||||||
|
local ok, err = pcall(function ()
|
||||||
|
if code:sub(1, 1) == "=" then
|
||||||
|
code = "return " .. code:sub(2)
|
||||||
|
end
|
||||||
|
print(assert(load(code))())
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
TERM.write(tostring(err) .. "\r\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if termClose then
|
||||||
|
termClose()
|
||||||
|
end
|
||||||
|
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- app-taskmgr: Task manager
|
-- app-taskmgr: Task manager
|
||||||
-- a-hello : simple test program for Everest.
|
-- a-hello : simple test program for Everest.
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- 'neolithic': Text Editor
|
-- 'neolithic': Text Editor
|
||||||
-- This was textedit (femto) from KittenOS 'ported' to NEO.
|
-- This was textedit (femto) from KittenOS 'ported' to NEO.
|
||||||
@ -11,7 +15,7 @@ local lines = {
|
|||||||
"F5, F6, ^←: Copy, Paste, Delete Line",
|
"F5, F6, ^←: Copy, Paste, Delete Line",
|
||||||
-- These two are meant to replace similar functionality in GNU Nano
|
-- These two are meant to replace similar functionality in GNU Nano
|
||||||
-- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that),
|
-- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that),
|
||||||
-- except fixing a UI flaw by instead making J responsible for resetting the append flag,
|
-- except fixing a UI flaw by instead adding a visible way to reset the append flag,
|
||||||
-- so the user can more or less arbitrarily mash together lines
|
-- so the user can more or less arbitrarily mash together lines
|
||||||
"F7: Reset 'append' flag for Cut Lines",
|
"F7: Reset 'append' flag for Cut Lines",
|
||||||
"F8: Cut Line(s)",
|
"F8: Cut Line(s)",
|
||||||
@ -30,33 +34,17 @@ local clipsrc = neo.requireAccess("x.neo.pub.globals", "clipboard")
|
|||||||
local windows = neo.requireAccess("x.neo.pub.window", "windows")
|
local windows = neo.requireAccess("x.neo.pub.window", "windows")
|
||||||
local files = neo.requireAccess("x.neo.pub.base", "files").showFileDialogAsync
|
local files = neo.requireAccess("x.neo.pub.base", "files").showFileDialogAsync
|
||||||
|
|
||||||
|
local lineEdit = require("lineedit")
|
||||||
|
|
||||||
local cursorX = 1
|
local cursorX = 1
|
||||||
local cursorY = math.ceil(#lines / 2)
|
local cursorY = math.ceil(#lines / 2)
|
||||||
local cFlash = true
|
local ctrlFlag, appendFlag
|
||||||
local ctrlFlag = false
|
|
||||||
local dialogLock = false
|
local dialogLock = false
|
||||||
local appendFlag = false
|
|
||||||
local sW, sH = 37, #lines + 2
|
local sW, sH = 37, #lines + 2
|
||||||
local window = windows(sW, sH)
|
local window = windows(sW, sH)
|
||||||
local filedialog = nil
|
local filedialog = nil
|
||||||
local flush
|
local flush
|
||||||
|
|
||||||
local function splitCur()
|
|
||||||
local s = lines[cursorY]
|
|
||||||
local st = unicode.sub(s, 1, cursorX - 1)
|
|
||||||
local en = unicode.sub(s, cursorX)
|
|
||||||
return st, en
|
|
||||||
end
|
|
||||||
|
|
||||||
local function clampCursorX()
|
|
||||||
local s = lines[cursorY]
|
|
||||||
if unicode.len(s) < (cursorX - 1) then
|
|
||||||
cursorX = unicode.len(s) + 1
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local cbs = {}
|
local cbs = {}
|
||||||
|
|
||||||
local function fileDialog(writing, callback)
|
local function fileDialog(writing, callback)
|
||||||
@ -140,31 +128,14 @@ local function getline(y)
|
|||||||
-- rX is difficult!
|
-- rX is difficult!
|
||||||
local rX = 1
|
local rX = 1
|
||||||
local Xthold = math.max(1, math.floor(sW / 2) - 1)
|
local Xthold = math.max(1, math.floor(sW / 2) - 1)
|
||||||
local _, cursorXP = unicode.safeTextFormat(lines[cursorY], cursorX)
|
local cLine, cursorXP = unicode.safeTextFormat(lines[cursorY], cursorX)
|
||||||
rX = (math.max(0, math.floor(cursorXP / Xthold) - 1) * Xthold) + 1
|
rX = (math.max(0, math.floor(cursorXP / Xthold) - 1) * Xthold) + 1
|
||||||
local line = lines[rY]
|
local line = lines[rY]
|
||||||
if not line then
|
if not line then
|
||||||
return ("¬"):rep(sW)
|
return ("¬"):rep(sW)
|
||||||
end
|
end
|
||||||
line = unicode.safeTextFormat(line)
|
line = unicode.safeTextFormat(line)
|
||||||
-- <alter RX here by 1 if needed>
|
return lineEdit.draw(sW, line, rY == cursorY and cursorXP, rX)
|
||||||
local tl = unicode.sub(line, rX, rX + sW - 1)
|
|
||||||
cursorXP = (cursorXP - rX) + 1
|
|
||||||
if cFlash then
|
|
||||||
if rY == cursorY then
|
|
||||||
if cursorXP >= 1 then
|
|
||||||
if cursorXP <= sW then
|
|
||||||
local start = unicode.sub(tl, 1, cursorXP - 1)
|
|
||||||
local endx = unicode.sub(tl, cursorXP + 1)
|
|
||||||
tl = start .. "_" .. endx
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
while unicode.len(tl) < sW do
|
|
||||||
tl = tl .. " "
|
|
||||||
end
|
|
||||||
return tl
|
|
||||||
end
|
end
|
||||||
local function delLine()
|
local function delLine()
|
||||||
local contents = lines[cursorY]
|
local contents = lines[cursorY]
|
||||||
@ -180,22 +151,7 @@ local function delLine()
|
|||||||
end
|
end
|
||||||
return contents
|
return contents
|
||||||
end
|
end
|
||||||
-- add a single character
|
local function key(ks, kc, down)
|
||||||
local function putLetter(ch)
|
|
||||||
if ch == "\r" then
|
|
||||||
local a, b = splitCur()
|
|
||||||
lines[cursorY] = a
|
|
||||||
table.insert(lines, cursorY + 1, b)
|
|
||||||
cursorY = cursorY + 1
|
|
||||||
cursorX = 1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local a, b = splitCur()
|
|
||||||
a = a .. ch
|
|
||||||
lines[cursorY] = a .. b
|
|
||||||
cursorX = unicode.len(a) + 1
|
|
||||||
end
|
|
||||||
local function key(ka, kc, down)
|
|
||||||
if dialogLock then
|
if dialogLock then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -213,23 +169,23 @@ local function key(ka, kc, down)
|
|||||||
sH = 1
|
sH = 1
|
||||||
end
|
end
|
||||||
sW, sH = window.setSize(sW, sH)
|
sW, sH = window.setSize(sW, sH)
|
||||||
end
|
return false
|
||||||
if kc == 208 then -- Down
|
elseif kc == 208 then -- Down
|
||||||
sH = sH + 1
|
sH = sH + 1
|
||||||
sW, sH = window.setSize(sW, sH)
|
sW, sH = window.setSize(sW, sH)
|
||||||
end
|
return false
|
||||||
if kc == 203 then -- Left
|
elseif kc == 203 then -- Left
|
||||||
sW = sW - 1
|
sW = sW - 1
|
||||||
if sW == 0 then
|
if sW == 0 then
|
||||||
sW = 1
|
sW = 1
|
||||||
end
|
end
|
||||||
sW, sH = window.setSize(sW, sH)
|
sW, sH = window.setSize(sW, sH)
|
||||||
end
|
return false
|
||||||
if kc == 205 then -- Right
|
elseif kc == 205 then -- Right
|
||||||
sW = sW + 1
|
sW = sW + 1
|
||||||
sW, sH = window.setSize(sW, sH)
|
sW, sH = window.setSize(sW, sH)
|
||||||
end
|
return false
|
||||||
if kc == 14 then -- ^Backspace
|
elseif kc == 14 then -- ^Backspace
|
||||||
delLine()
|
delLine()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -245,10 +201,9 @@ local function key(ka, kc, down)
|
|||||||
if cursorY < 1 then
|
if cursorY < 1 then
|
||||||
cursorY = 1
|
cursorY = 1
|
||||||
end
|
end
|
||||||
clampCursorX()
|
cursorX = lineEdit.clamp(lines[cursorY], cursorX)
|
||||||
return true
|
return true
|
||||||
end
|
elseif kc == 208 or kc == 209 then -- Go down one - go down page
|
||||||
if kc == 208 or kc == 209 then -- Go down one - go down page
|
|
||||||
local moveAmount = 1
|
local moveAmount = 1
|
||||||
if kc == 209 then
|
if kc == 209 then
|
||||||
moveAmount = math.floor(sH / 2)
|
moveAmount = math.floor(sH / 2)
|
||||||
@ -257,39 +212,7 @@ local function key(ka, kc, down)
|
|||||||
if cursorY > #lines then
|
if cursorY > #lines then
|
||||||
cursorY = #lines
|
cursorY = #lines
|
||||||
end
|
end
|
||||||
clampCursorX()
|
cursorX = lineEdit.clamp(lines[cursorY], cursorX)
|
||||||
return true
|
|
||||||
end
|
|
||||||
if kc == 203 then
|
|
||||||
if cursorX > 1 then
|
|
||||||
cursorX = cursorX - 1
|
|
||||||
else
|
|
||||||
if cursorY > 1 then
|
|
||||||
cursorY = cursorY - 1
|
|
||||||
cursorX = unicode.len(lines[cursorY]) + 1
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
if kc == 205 then
|
|
||||||
cursorX = cursorX + 1
|
|
||||||
if clampCursorX() then
|
|
||||||
if cursorY < #lines then
|
|
||||||
cursorY = cursorY + 1
|
|
||||||
cursorX = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
-- Extra Non-Control Keys
|
|
||||||
if kc == 199 then
|
|
||||||
cursorX = 1
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
if kc == 207 then
|
|
||||||
cursorX = unicode.len(lines[cursorY]) + 1
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
-- Major Actions
|
-- Major Actions
|
||||||
@ -298,17 +221,16 @@ local function key(ka, kc, down)
|
|||||||
cursorX = 1
|
cursorX = 1
|
||||||
cursorY = 1
|
cursorY = 1
|
||||||
return true
|
return true
|
||||||
end
|
elseif kc == 61 then -- F3
|
||||||
if kc == 61 then -- F3
|
|
||||||
startLoad()
|
startLoad()
|
||||||
end
|
return false
|
||||||
if kc == 62 then -- F4
|
elseif kc == 62 then -- F4
|
||||||
startSave()
|
startSave()
|
||||||
end
|
return false
|
||||||
if kc == 63 then -- F5
|
elseif kc == 63 then -- F5
|
||||||
clipsrc.setSetting("clipboard", lines[cursorY])
|
clipsrc.setSetting("clipboard", lines[cursorY])
|
||||||
end
|
return false
|
||||||
if kc == 64 then -- F6
|
elseif kc == 64 then -- F6
|
||||||
local tx = clipsrc.getSetting("clipboard") or ""
|
local tx = clipsrc.getSetting("clipboard") or ""
|
||||||
local txi = tx:find("\n")
|
local txi = tx:find("\n")
|
||||||
local nt = {}
|
local nt = {}
|
||||||
@ -322,11 +244,10 @@ local function key(ka, kc, down)
|
|||||||
table.insert(lines, cursorY, v)
|
table.insert(lines, cursorY, v)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
elseif kc == 65 then -- F7
|
||||||
if kc == 65 then -- F7
|
|
||||||
appendFlag = false
|
appendFlag = false
|
||||||
end
|
return false
|
||||||
if kc == 66 then -- F8
|
elseif kc == 66 then -- F8
|
||||||
if appendFlag then
|
if appendFlag then
|
||||||
local base = clipsrc.getSetting("clipboard")
|
local base = clipsrc.getSetting("clipboard")
|
||||||
clipsrc.setSetting("clipboard", base .. "\n" .. delLine())
|
clipsrc.setSetting("clipboard", base .. "\n" .. delLine())
|
||||||
@ -337,29 +258,37 @@ local function key(ka, kc, down)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Letters
|
-- LEL Keys
|
||||||
if ka == 8 or kc == 211 then
|
local lT, lC, lX = lineEdit.key(ks, kc, lines[cursorY], cursorX)
|
||||||
if cursorX == 1 then
|
if lT then
|
||||||
if cursorY == 1 then
|
lines[cursorY] = lT
|
||||||
return false
|
|
||||||
end
|
|
||||||
local l = table.remove(lines, cursorY)
|
|
||||||
cursorY = cursorY - 1
|
|
||||||
cursorX = unicode.len(lines[cursorY]) + 1
|
|
||||||
lines[cursorY] = lines[cursorY] .. l
|
|
||||||
else
|
|
||||||
local a, b = splitCur()
|
|
||||||
a = unicode.sub(a, 1, unicode.len(a) - 1)
|
|
||||||
lines[cursorY] = a.. b
|
|
||||||
cursorX = cursorX - 1
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
if ka ~= 0 then
|
if lC then
|
||||||
putLetter(unicode.char(ka))
|
cursorX = lC
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
return false
|
if lX == "l<" and cursorY > 1 then
|
||||||
|
cursorY = cursorY - 1
|
||||||
|
cursorX = unicode.len(lines[cursorY]) + 1
|
||||||
|
elseif lX == "l>" and cursorY < #lines then
|
||||||
|
cursorY = cursorY + 1
|
||||||
|
cursorX = 1
|
||||||
|
elseif lX == "w<" and cursorY ~= 1 then
|
||||||
|
local l = table.remove(lines, cursorY)
|
||||||
|
cursorY = cursorY - 1
|
||||||
|
cursorX = unicode.len(lines[cursorY]) + 1
|
||||||
|
lines[cursorY] = lines[cursorY] .. l
|
||||||
|
elseif lX == "w>" and cursorY ~= #lines then
|
||||||
|
local l = table.remove(lines, cursorY)
|
||||||
|
cursorX = unicode.len(l) + 1
|
||||||
|
lines[cursorY] = l .. lines[cursorY]
|
||||||
|
elseif lX == "nl" then
|
||||||
|
local line = lines[cursorY]
|
||||||
|
lines[cursorY] = unicode.sub(line, 1, cursorX - 1)
|
||||||
|
table.insert(lines, cursorY + 1, unicode.sub(line, cursorX))
|
||||||
|
cursorX = 1
|
||||||
|
cursorY = cursorY + 1
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
flush = function ()
|
flush = function ()
|
||||||
@ -368,16 +297,9 @@ flush = function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neo.scheduleTimer(os.uptime() + 0.5)
|
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local e = {coroutine.yield()}
|
local e = {coroutine.yield()}
|
||||||
if e[1] == "k.timer" then
|
if e[1] == "x.neo.pub.window" then
|
||||||
cFlash = not cFlash
|
|
||||||
local csY = math.ceil(sH / 2)
|
|
||||||
window.span(1, csY, getline(csY), 0xFFFFFF, 0)
|
|
||||||
neo.scheduleTimer(os.uptime() + 0.5)
|
|
||||||
elseif e[1] == "x.neo.pub.window" then
|
|
||||||
if e[2] == window.id then
|
if e[2] == window.id then
|
||||||
if e[3] == "line" then
|
if e[3] == "line" then
|
||||||
window.span(1, e[4], getline(e[4]), 0xFFFFFF, 0)
|
window.span(1, e[4], getline(e[4]), 0xFFFFFF, 0)
|
||||||
@ -388,10 +310,10 @@ while true do
|
|||||||
local csY = math.ceil(sH / 2)
|
local csY = math.ceil(sH / 2)
|
||||||
local nY = math.max(1, math.min(#lines, (math.floor(e[5]) - csY) + cursorY))
|
local nY = math.max(1, math.min(#lines, (math.floor(e[5]) - csY) + cursorY))
|
||||||
cursorY = nY
|
cursorY = nY
|
||||||
clampCursorX()
|
cursorX = lineEdit.clamp(lines[cursorY], cursorX)
|
||||||
flush()
|
flush()
|
||||||
elseif e[3] == "key" then
|
elseif e[3] == "key" then
|
||||||
if key(e[4], e[5], e[6]) then
|
if key(e[4] ~= 0 and unicode.char(e[4]), e[5], e[6]) then
|
||||||
flush()
|
flush()
|
||||||
end
|
end
|
||||||
elseif e[3] == "focus" then
|
elseif e[3] == "focus" then
|
||||||
@ -406,7 +328,7 @@ while true do
|
|||||||
if c == "\n" then
|
if c == "\n" then
|
||||||
c = "\r"
|
c = "\r"
|
||||||
end
|
end
|
||||||
putLetter(c)
|
key(c, 0, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
flush()
|
flush()
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
local neoux = require("neoux")(event, neo)
|
local neoux = require("neoux")(event, neo)
|
||||||
|
159
code/apps/svc-app-claw-worker.lua
Normal file
159
code/apps/svc-app-claw-worker.lua
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- svc-app-claw-worker: Who stays stays. Who goes goes.
|
||||||
|
|
||||||
|
local callerPkg, _, destProx, packageId, downloadSrc, checked, primaryINet = ...
|
||||||
|
if callerPkg ~= "app-claw" then error("Internal process for app-claw's bidding.") end
|
||||||
|
-- This 'mutex' remains active as long as the process does.
|
||||||
|
neo.requireAccess("r.svc.app-claw-worker", "CLAW mutex")
|
||||||
|
|
||||||
|
local function wrapLines(ocb)
|
||||||
|
local buf = ""
|
||||||
|
return function (data)
|
||||||
|
if not data then
|
||||||
|
ocb(buf)
|
||||||
|
else
|
||||||
|
buf = buf .. data
|
||||||
|
buf = buf:gsub("[^\n]*\n", function (t)
|
||||||
|
ocb(t:sub(1, -2))
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function download(url, cb, src)
|
||||||
|
if type(src) == "string" then
|
||||||
|
assert(primaryINet, "no internet")
|
||||||
|
local req, err = primaryINet.request(src .. url)
|
||||||
|
assert(req, err)
|
||||||
|
-- OpenComputers#535
|
||||||
|
req.finishConnect()
|
||||||
|
while true do
|
||||||
|
local n, n2 = req.read(neo.readBufSize)
|
||||||
|
cb(n)
|
||||||
|
if not n then
|
||||||
|
req.close()
|
||||||
|
if n2 then
|
||||||
|
error(n2)
|
||||||
|
else
|
||||||
|
cb(nil)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if n == "" then
|
||||||
|
neo.scheduleTimer(os.uptime() + 0.05)
|
||||||
|
while true do
|
||||||
|
local res = coroutine.yield()
|
||||||
|
if res == "k.timer" then break end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local h, e = src.open(url, "rb")
|
||||||
|
assert(h, e)
|
||||||
|
repeat
|
||||||
|
local c = src.read(h, neo.readBufSize)
|
||||||
|
cb(c)
|
||||||
|
until not c
|
||||||
|
src.close(h)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local opInstall, opRemove
|
||||||
|
|
||||||
|
function opInstall(packageId, checked)
|
||||||
|
local gback = {} -- the ultimate strategy
|
||||||
|
local gdir = {}
|
||||||
|
local preinstall = {}
|
||||||
|
download("data/app-claw/" .. packageId .. ".c2x", wrapLines(function (l)
|
||||||
|
if l:sub(1, 1) == "?" and checked then
|
||||||
|
preinstall[l:sub(2)] = true
|
||||||
|
elseif l:sub(1, 1) == "+" then
|
||||||
|
table.insert(gback, l:sub(2))
|
||||||
|
elseif l:sub(1, 1) == "/" then
|
||||||
|
table.insert(gdir, l:sub(2))
|
||||||
|
end
|
||||||
|
end), downloadSrc)
|
||||||
|
for _, v in ipairs(gdir) do
|
||||||
|
destProx.makeDirectory(v)
|
||||||
|
assert(destProx.isDirectory(v), "unable to create dir " .. v)
|
||||||
|
end
|
||||||
|
gdir = nil
|
||||||
|
for k, _ in pairs(preinstall) do
|
||||||
|
if not destProx.exists("data/app-claw/" .. k .. ".c2x") then
|
||||||
|
opInstall(k, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
preinstall = nil
|
||||||
|
for _, v in ipairs(gback) do
|
||||||
|
local f = destProx.open(v .. ".C2T", "wb")
|
||||||
|
assert(f, "unable to create download file")
|
||||||
|
local ok, e = pcall(download, v, function (b)
|
||||||
|
assert(destProx.write(f, b or ""), "unable to save data")
|
||||||
|
end, downloadSrc)
|
||||||
|
destProx.close(f)
|
||||||
|
if not ok then error(e) end
|
||||||
|
end
|
||||||
|
-- CRITICAL SECTION --
|
||||||
|
if destProx.exists("data/app-claw/" .. packageId .. ".c2x") then
|
||||||
|
opRemove(packageId, false)
|
||||||
|
end
|
||||||
|
for _, v in ipairs(gback) do
|
||||||
|
if destProx.exists(v) then
|
||||||
|
for _, v in ipairs(gback) do
|
||||||
|
destProx.remove(v .. ".C2T")
|
||||||
|
end
|
||||||
|
error("file conflict: " .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, v in ipairs(gback) do
|
||||||
|
destProx.rename(v .. ".C2T", v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function opRemove(packageId, checked)
|
||||||
|
if checked then
|
||||||
|
local dependents = {}
|
||||||
|
for _, pidf in ipairs(destProx.list("data/app-claw/")) do
|
||||||
|
if pidf:sub(-4) == ".c2x" then
|
||||||
|
local pid = pidf:sub(1, -5)
|
||||||
|
download("data/app-claw/" .. pidf, wrapLines(function (l)
|
||||||
|
if l == "?" .. packageId then
|
||||||
|
table.insert(dependents, pid)
|
||||||
|
end
|
||||||
|
end), destProx)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(not dependents[1], "Cannot remove " .. packageId .. ", required by:\n" .. table.concat(dependents, ", "))
|
||||||
|
end
|
||||||
|
local rmSchedule = {}
|
||||||
|
download("data/app-claw/" .. packageId .. ".c2x", wrapLines(function (l)
|
||||||
|
if l:sub(1, 1) == "+" then
|
||||||
|
table.insert(rmSchedule, l:sub(2))
|
||||||
|
end
|
||||||
|
end), destProx)
|
||||||
|
for _, v in ipairs(rmSchedule) do
|
||||||
|
destProx.remove(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, e
|
||||||
|
if downloadSrc then
|
||||||
|
ok, e = pcall(opInstall, packageId, checked)
|
||||||
|
else
|
||||||
|
ok, e = pcall(opRemove, packageId, checked)
|
||||||
|
end
|
||||||
|
destProx = nil
|
||||||
|
downloadSrc = nil
|
||||||
|
primaryINet = nil
|
||||||
|
neo.executeAsync("app-claw", packageId)
|
||||||
|
if not ok then
|
||||||
|
error(e)
|
||||||
|
end
|
495
code/apps/svc-t.lua
Normal file
495
code/apps/svc-t.lua
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- svc-t.lua : terminal
|
||||||
|
|
||||||
|
local _, _, retTbl, title = ...
|
||||||
|
|
||||||
|
assert(retTbl, "need to alert creator")
|
||||||
|
|
||||||
|
if title ~= nil then
|
||||||
|
assert(type(title) == "string", "title must be string")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rW()
|
||||||
|
return string.format("%04x", math.random(0, 65535))
|
||||||
|
end
|
||||||
|
|
||||||
|
local id = "neo.pub.t/" .. rW() .. rW() .. rW() .. rW()
|
||||||
|
local closeNow = false
|
||||||
|
|
||||||
|
-- Terminus Registration State --
|
||||||
|
|
||||||
|
local tReg = neo.requireAccess("r." .. id, "registration")
|
||||||
|
local sendSigs = {}
|
||||||
|
|
||||||
|
-- Display State --
|
||||||
|
-- unicode.safeTextFormat'd lines.
|
||||||
|
-- The size of this must not go below 1.
|
||||||
|
local console = {}
|
||||||
|
-- This must not go below 3.
|
||||||
|
local conW = 40
|
||||||
|
local conCX, conCY = 1, 1
|
||||||
|
local conSCX, conSCY = 1, 1
|
||||||
|
-- Performance
|
||||||
|
local consoleShown = {}
|
||||||
|
local conCYShown
|
||||||
|
for i = 1, 14 do
|
||||||
|
console[i] = (" "):rep(conW)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Line Editing State --
|
||||||
|
-- Nil if line editing is off.
|
||||||
|
-- In this case, the console height
|
||||||
|
-- must be adjusted accordingly.
|
||||||
|
local leText = ""
|
||||||
|
-- These are NOT nil'd out,
|
||||||
|
-- particularly not the history buffer.
|
||||||
|
local leCX = 1
|
||||||
|
local leHistory = {
|
||||||
|
-- Size = history buffer size
|
||||||
|
"", "", "", ""
|
||||||
|
}
|
||||||
|
local function cycleHistoryUp()
|
||||||
|
local backupFirst = leHistory[1]
|
||||||
|
for i = 1, #leHistory - 1 do
|
||||||
|
leHistory[i] = leHistory[i + 1]
|
||||||
|
end
|
||||||
|
leHistory[#leHistory] = backupFirst
|
||||||
|
end
|
||||||
|
local function cycleHistoryDown()
|
||||||
|
local backup = leHistory[1]
|
||||||
|
for i = 2, #leHistory do
|
||||||
|
backup, leHistory[i] = leHistory[i], backup
|
||||||
|
end
|
||||||
|
leHistory[1] = backup
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Window --
|
||||||
|
|
||||||
|
local window = neo.requireAccess("x.neo.pub.window", "window")(conW, #console + 1, title)
|
||||||
|
|
||||||
|
-- Core Terminal Functions --
|
||||||
|
|
||||||
|
local function setSize(w, h)
|
||||||
|
conW = w
|
||||||
|
for i = 1, #console do
|
||||||
|
consoleShown[i] = nil
|
||||||
|
end
|
||||||
|
while #console < h do
|
||||||
|
table.insert(console, "")
|
||||||
|
end
|
||||||
|
while #console > h do
|
||||||
|
table.remove(console, 1)
|
||||||
|
end
|
||||||
|
for i = 1, #console do
|
||||||
|
console[i] = unicode.sub(console[i], 1, w) .. (" "):rep(w - unicode.len(console[i]))
|
||||||
|
end
|
||||||
|
if leText then
|
||||||
|
window.setSize(w, h + 1)
|
||||||
|
else
|
||||||
|
window.setSize(w, h)
|
||||||
|
end
|
||||||
|
conCX, conCY = 1, h
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setLineEditing(state)
|
||||||
|
if state and not leText then
|
||||||
|
leText = ""
|
||||||
|
leCX = 1
|
||||||
|
setSize(conW, #console)
|
||||||
|
elseif leText and not state then
|
||||||
|
leText = nil
|
||||||
|
setSize(conW, #console)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function draw(i)
|
||||||
|
if console[i] then
|
||||||
|
window.span(1, i, console[i], 0, 0xFFFFFF)
|
||||||
|
if i == conCY and not leText then
|
||||||
|
window.span(conCX, i, unicode.sub(console[i], conCX, conCX), 0xFFFFFF, 0)
|
||||||
|
end
|
||||||
|
elseif leText then
|
||||||
|
window.span(1, i, require("lineedit").draw(conW, unicode.safeTextFormat(leText, leCX)), 0xFFFFFF, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function drawDisplay()
|
||||||
|
for i = 1, #console do
|
||||||
|
if consoleShown[i] ~= console[i] or i == conCY or i == conCYShown then
|
||||||
|
draw(i)
|
||||||
|
consoleShown[i] = console[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
conCYShown = conCY
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Terminal Visual --
|
||||||
|
|
||||||
|
local function consoleSD()
|
||||||
|
for i = 1, #console - 1 do
|
||||||
|
console[i] = console[i + 1]
|
||||||
|
end
|
||||||
|
console[#console] = (" "):rep(conW)
|
||||||
|
end
|
||||||
|
local function consoleSU()
|
||||||
|
local backup = (" "):rep(conW)
|
||||||
|
for i = 1, #console do
|
||||||
|
backup, console[i] = console[i], backup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function consoleCLS()
|
||||||
|
for i = 1, #console do
|
||||||
|
console[i] = (" "):rep(conW)
|
||||||
|
end
|
||||||
|
conCX, conCY = 1, 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function writeFF()
|
||||||
|
if conCY ~= #console then
|
||||||
|
conCY = conCY + 1
|
||||||
|
else
|
||||||
|
consoleSD()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function writeData(data)
|
||||||
|
-- handle data until completion
|
||||||
|
while #data > 0 do
|
||||||
|
local char = unicode.sub(data, 1, 1)
|
||||||
|
--neo.emergency("svc-t.data: " .. char:byte())
|
||||||
|
data = unicode.sub(data, 2)
|
||||||
|
-- handle character
|
||||||
|
if char == "\t" then
|
||||||
|
-- not ideal, but allowed
|
||||||
|
char = " "
|
||||||
|
end
|
||||||
|
if char == "\r" then
|
||||||
|
conCX = 1
|
||||||
|
elseif char == "\x00" then
|
||||||
|
-- caused by TELNET \r rules
|
||||||
|
elseif char == "\n" then
|
||||||
|
conCX = 1
|
||||||
|
writeFF()
|
||||||
|
elseif char == "\a" then
|
||||||
|
-- Bell (er...)
|
||||||
|
elseif char == "\b" then
|
||||||
|
conCX = math.max(1, conCX - 1)
|
||||||
|
elseif char == "\v" or char == "\f" then
|
||||||
|
writeFF()
|
||||||
|
else
|
||||||
|
local charL = unicode.wlen(char)
|
||||||
|
if (conCX + charL - 1) > conW then
|
||||||
|
conCX = 1
|
||||||
|
writeFF()
|
||||||
|
end
|
||||||
|
local spaces = (" "):rep(charL - 1)
|
||||||
|
console[conCY] = unicode.sub(console[conCY], 1, conCX - 1) .. char .. spaces .. unicode.sub(console[conCY], conCX + charL)
|
||||||
|
conCX = conCX + charL
|
||||||
|
-- Cursor can be (intentionally!) off-screen here
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function writeANSI(s)
|
||||||
|
--neo.emergency("svc-t.ansi: " .. s)
|
||||||
|
-- This supports just about enough to get by.
|
||||||
|
if s == "c" then
|
||||||
|
consoleCLS()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pfx = s:sub(1, 1)
|
||||||
|
local cmd = s:sub(#s)
|
||||||
|
if pfx == "[" then
|
||||||
|
local np = tonumber(s:sub(2, -2)) or 1
|
||||||
|
if cmd == "A" then
|
||||||
|
conCY = conCY - np
|
||||||
|
elseif cmd == "B" then
|
||||||
|
conCY = conCY + np
|
||||||
|
elseif cmd == "C" then
|
||||||
|
conCX = conCX + np
|
||||||
|
elseif cmd == "D" then
|
||||||
|
conCX = conCX - np
|
||||||
|
elseif cmd == "f" or cmd == "H" then
|
||||||
|
local p = s:find(";")
|
||||||
|
if not p then
|
||||||
|
conCY = np
|
||||||
|
conCX = 1
|
||||||
|
else
|
||||||
|
conCY = tonumber(s:sub(2, p - 1)) or 1
|
||||||
|
conCX = tonumber(s:sub(p + 1, -2)) or 1
|
||||||
|
end
|
||||||
|
elseif cmd == "J" then
|
||||||
|
consoleCLS()
|
||||||
|
elseif cmd == "K" then
|
||||||
|
if s == "[K" or s == "[0K" then
|
||||||
|
-- bash needs this
|
||||||
|
console[conCY] = unicode.sub(console[conCY], 1, conCX - 1) .. (" "):rep(1 + conW - conCX)
|
||||||
|
else
|
||||||
|
console[conCY] = (" "):rep(conW)
|
||||||
|
end
|
||||||
|
elseif cmd == "n" then
|
||||||
|
if s == "[6n" then
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("data", "\x1b[" .. conY .. ";" .. conX .. "R")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif cmd == "s" then
|
||||||
|
conSCX, conSCY = conCX, conCY
|
||||||
|
elseif cmd == "u" then
|
||||||
|
conCX, conCY = conSCX, conSCY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
conCX = math.min(math.max(math.floor(conCX), 1), conW)
|
||||||
|
conCY = math.min(math.max(math.floor(conCY), 1), #console)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The Terminus --
|
||||||
|
|
||||||
|
local tvBuildingCmd = ""
|
||||||
|
local tvBuildingUTF = ""
|
||||||
|
local tvSubnegotiation = false
|
||||||
|
local function incoming(s)
|
||||||
|
tvBuildingCmd = tvBuildingCmd .. s
|
||||||
|
-- Flush Cmd
|
||||||
|
while #tvBuildingCmd > 0 do
|
||||||
|
if tvBuildingCmd:byte() == 255 then
|
||||||
|
-- It's a command. Uhoh.
|
||||||
|
if #tvBuildingCmd < 2 then break end
|
||||||
|
local cmd = tvBuildingCmd:byte(2)
|
||||||
|
local param = tvBuildingCmd:byte(3)
|
||||||
|
local cmdLen = 2
|
||||||
|
-- Command Lengths
|
||||||
|
if cmd >= 251 and cmd <= 254 then cmdLen = 3 end
|
||||||
|
if #tvBuildingCmd < cmdLen then break end
|
||||||
|
if cmd == 240 then
|
||||||
|
-- SE
|
||||||
|
tvSubnegotiation = false
|
||||||
|
elseif cmd == 250 then
|
||||||
|
-- SB
|
||||||
|
tvSubnegotiation = true
|
||||||
|
elseif cmd == 251 and param == 1 then
|
||||||
|
-- WILL ECHO (respond with DO ECHO, disable line editing)
|
||||||
|
-- test using io.write("\xFF\xFB\x01")
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("telnet", "\xFF\xFD\x01")
|
||||||
|
end
|
||||||
|
setLineEditing(false)
|
||||||
|
elseif cmd == 252 and param == 1 then
|
||||||
|
-- WON'T ECHO (respond with DON'T ECHO, enable line editing)
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("telnet", "\xFF\xFE\x01")
|
||||||
|
end
|
||||||
|
setLineEditing(true)
|
||||||
|
elseif cmd == 251 or cmd == 252 then
|
||||||
|
-- WILL/WON'T (x) (respond with DON'T (X))
|
||||||
|
local res = "\xFF\xFE" .. string.char(param)
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("telnet", res)
|
||||||
|
end
|
||||||
|
elseif cmd == 253 or cmd == 254 then
|
||||||
|
-- DO/DON'T (x) (respond with WON'T (X))
|
||||||
|
local res = "\xFF\xFC" .. string.char(param)
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("telnet", res)
|
||||||
|
end
|
||||||
|
elseif cmd == 255 then
|
||||||
|
if not tvSubnegotiation then
|
||||||
|
tvBuildingUTF = tvBuildingUTF .. "\xFF"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tvBuildingCmd = tvBuildingCmd:sub(cmdLen + 1)
|
||||||
|
else
|
||||||
|
if not tvSubnegotiation then
|
||||||
|
tvBuildingUTF = tvBuildingUTF .. tvBuildingCmd:sub(1, 1)
|
||||||
|
end
|
||||||
|
tvBuildingCmd = tvBuildingCmd:sub(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Flush UTF/Display
|
||||||
|
while #tvBuildingUTF > 0 do
|
||||||
|
local head = tvBuildingUTF:byte()
|
||||||
|
local len = 1
|
||||||
|
local handled = false
|
||||||
|
if head == 27 then
|
||||||
|
local h2 = tvBuildingUTF:byte(2)
|
||||||
|
if h2 == 91 then
|
||||||
|
for i = 3, #tvBuildingUTF do
|
||||||
|
local cmd = tvBuildingUTF:byte(i)
|
||||||
|
if cmd >= 0x40 and cmd <= 0x7E then
|
||||||
|
writeANSI(tvBuildingUTF:sub(2, i))
|
||||||
|
len = i
|
||||||
|
handled = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif h2 then
|
||||||
|
len = 2
|
||||||
|
writeANSI(tvBuildingUTF:sub(2, 2))
|
||||||
|
handled = true
|
||||||
|
end
|
||||||
|
if not handled then break end
|
||||||
|
end
|
||||||
|
if not handled then
|
||||||
|
if head < 192 then
|
||||||
|
len = 1
|
||||||
|
elseif head < 224 then
|
||||||
|
len = 2
|
||||||
|
elseif head < 240 then
|
||||||
|
len = 3
|
||||||
|
elseif head < 248 then
|
||||||
|
len = 4
|
||||||
|
elseif head < 252 then
|
||||||
|
len = 5
|
||||||
|
elseif head < 254 then
|
||||||
|
len = 6
|
||||||
|
end
|
||||||
|
if #tvBuildingUTF < len then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- verified one full character...
|
||||||
|
writeData(tvBuildingUTF:sub(1, len))
|
||||||
|
end
|
||||||
|
tvBuildingUTF = tvBuildingUTF:sub(len + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
tReg(function (_, pid, sendSig)
|
||||||
|
sendSigs[pid] = sendSig
|
||||||
|
return {
|
||||||
|
id = "x." .. id,
|
||||||
|
pid = neo.pid,
|
||||||
|
write = function (text)
|
||||||
|
incoming(tostring(text))
|
||||||
|
drawDisplay()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end, true)
|
||||||
|
|
||||||
|
if retTbl then
|
||||||
|
coroutine.resume(coroutine.create(retTbl), {
|
||||||
|
access = "x." .. id,
|
||||||
|
close = function ()
|
||||||
|
closeNow = true
|
||||||
|
neo.scheduleTimer(0)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local control = false
|
||||||
|
|
||||||
|
local function key(a, c)
|
||||||
|
if control then
|
||||||
|
if c == 203 and conW > 8 then
|
||||||
|
setSize(conW - 1, #console)
|
||||||
|
return
|
||||||
|
elseif c == 200 and #console > 1 then
|
||||||
|
setSize(conW, #console - 1)
|
||||||
|
return
|
||||||
|
elseif c == 205 then
|
||||||
|
setSize(conW + 1, #console)
|
||||||
|
return
|
||||||
|
elseif c == 208 then
|
||||||
|
setSize(conW, #console + 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- so with the reserved ones dealt with...
|
||||||
|
if not leText then
|
||||||
|
-- Line Editing not active.
|
||||||
|
-- For now support a bare minimum.
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
if a == "\x03" then
|
||||||
|
v("telnet", "\xFF\xF4")
|
||||||
|
elseif c == 199 then
|
||||||
|
v("data", "\x1b[H")
|
||||||
|
elseif c == 201 then
|
||||||
|
v("data", "\x1b[5~")
|
||||||
|
elseif c == 207 then
|
||||||
|
v("data", "\x1b[F")
|
||||||
|
elseif c == 209 then
|
||||||
|
v("data", "\x1b[6~")
|
||||||
|
elseif c == 203 then
|
||||||
|
v("data", "\x1b[D")
|
||||||
|
elseif c == 205 then
|
||||||
|
v("data", "\x1b[C")
|
||||||
|
elseif c == 200 then
|
||||||
|
v("data", "\x1b[A")
|
||||||
|
elseif c == 208 then
|
||||||
|
v("data", "\x1b[B")
|
||||||
|
elseif a == "\r" then
|
||||||
|
v("data", "\r\n")
|
||||||
|
elseif a then
|
||||||
|
v("data", a)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif not control then
|
||||||
|
-- Line Editing active and control isn't involved
|
||||||
|
if c == 200 or c == 208 then
|
||||||
|
-- History cursor up (history down)
|
||||||
|
leText = leHistory[#leHistory]
|
||||||
|
leCX = unicode.len(leText) + 1
|
||||||
|
if c == 208 then
|
||||||
|
cycleHistoryUp()
|
||||||
|
else
|
||||||
|
cycleHistoryDown()
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local lT, lC, lX = require("lineedit").key(a, c, leText, leCX)
|
||||||
|
leText = lT or leText
|
||||||
|
leCX = lC or leCX
|
||||||
|
if lX == "nl" then
|
||||||
|
cycleHistoryUp()
|
||||||
|
leHistory[#leHistory] = leText
|
||||||
|
-- the whole thing {
|
||||||
|
local fullText = leText .. "\r\n"
|
||||||
|
writeData(fullText)
|
||||||
|
drawDisplay()
|
||||||
|
for _, v in pairs(sendSigs) do
|
||||||
|
v("data", fullText)
|
||||||
|
end
|
||||||
|
-- }
|
||||||
|
leText = ""
|
||||||
|
leCX = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while not closeNow do
|
||||||
|
local e = {coroutine.yield()}
|
||||||
|
if e[1] == "k.procdie" then
|
||||||
|
sendSigs[e[3]] = nil
|
||||||
|
elseif e[1] == "x.neo.pub.window" then
|
||||||
|
if e[3] == "close" then
|
||||||
|
break
|
||||||
|
elseif e[3] == "clipboard" then
|
||||||
|
for i = 1, unicode.len(e[4]) do
|
||||||
|
local c = unicode.sub(e[4], i, i)
|
||||||
|
if c ~= "\r" then
|
||||||
|
if c == "\n" then
|
||||||
|
c = "\r"
|
||||||
|
end
|
||||||
|
key(c, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
draw(#console + 1)
|
||||||
|
elseif e[3] == "key" then
|
||||||
|
if e[5] == 29 or e[5] == 157 then
|
||||||
|
control = e[6]
|
||||||
|
elseif e[6] then
|
||||||
|
key(e[4] ~= 0 and unicode.char(e[4]), e[5])
|
||||||
|
draw(#console + 1)
|
||||||
|
end
|
||||||
|
elseif e[3] == "line" then
|
||||||
|
draw(e[4])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- s-everest
|
-- s-everest
|
||||||
|
|
||||||
@ -46,7 +50,7 @@ local monitors = {}
|
|||||||
-- This is where we stuff processes until monitors show up
|
-- This is where we stuff processes until monitors show up
|
||||||
monitors[0] = {nil, nil, 160, 50}
|
monitors[0] = {nil, nil, 160, 50}
|
||||||
|
|
||||||
-- {monitor, x, y, w, h, callback}
|
-- {monitor, x, y, w, h, callback, title}
|
||||||
-- callback events are:
|
-- callback events are:
|
||||||
-- key ka kc down
|
-- key ka kc down
|
||||||
-- line y
|
-- line y
|
||||||
@ -61,10 +65,12 @@ local shuttingDown = false
|
|||||||
-- Also used for settings.
|
-- Also used for settings.
|
||||||
local savingThrow = neo.requestAccess("x.neo.sys.manage")
|
local savingThrow = neo.requestAccess("x.neo.sys.manage")
|
||||||
|
|
||||||
|
local draggingWindowX, draggingWindowY
|
||||||
|
|
||||||
local function suggestAppsStop()
|
local function suggestAppsStop()
|
||||||
for k, v in ipairs(surfaces) do
|
for k, v in ipairs(surfaces) do
|
||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
v[6]("close")
|
v[6](v[8], "close")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -81,8 +87,8 @@ local function dying()
|
|||||||
-- If a process evades the deathtrap then it clearly has reason to stay alive regardless of Everest status.
|
-- If a process evades the deathtrap then it clearly has reason to stay alive regardless of Everest status.
|
||||||
-- Also note, should savingThrow fail, neo.dead is now a thing.
|
-- Also note, should savingThrow fail, neo.dead is now a thing.
|
||||||
for _, v in ipairs(surfaces) do
|
for _, v in ipairs(surfaces) do
|
||||||
pcall(v[6], "line", 1)
|
pcall(v[6], v[8], "line", 1)
|
||||||
pcall(v[6], "line", 2)
|
pcall(v[6], v[8], "line", 2)
|
||||||
end
|
end
|
||||||
surfaces = {}
|
surfaces = {}
|
||||||
end
|
end
|
||||||
@ -140,162 +146,13 @@ local function doBackgroundLine(m, mg, bdx, bdy, bdl)
|
|||||||
local str = unicode.sub(statusLine, bdx, bdx + bdl - 1)
|
local str = unicode.sub(statusLine, bdx, bdx + bdl - 1)
|
||||||
local strl = unicode.len(str)
|
local strl = unicode.len(str)
|
||||||
pcall(mg.set, bdx, bdy, unicode.undoSafeTextFormat(str))
|
pcall(mg.set, bdx, bdy, unicode.undoSafeTextFormat(str))
|
||||||
pcall(mg.fill, bdx + strl, bdy, bdl - strl, 1, " ")
|
pcall(mg.set, bdx + strl, bdy, (" "):rep(bdl - strl))
|
||||||
else
|
else
|
||||||
monitorGPUColours(m, mg, 0x000040, 0)
|
monitorGPUColours(m, mg, 0x000040, 0)
|
||||||
pcall(mg.fill, bdx, bdy, bdl, 1, " ")
|
pcall(mg.set, bdx, bdy, (" "):rep(bdl))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function updateRegion(monitorId, x, y, w, h, surfaceSpanCache)
|
|
||||||
if not renderingAllowed() then return end
|
|
||||||
local m = monitors[monitorId]
|
|
||||||
local mg, rb = m[1]()
|
|
||||||
if not mg then return end
|
|
||||||
if rb then
|
|
||||||
monitorResetBF(m)
|
|
||||||
end
|
|
||||||
-- The input region is the one that makes SENSE.
|
|
||||||
-- Considering WC handling, that's not an option.
|
|
||||||
-- WCHAX: start
|
|
||||||
if x > 1 then
|
|
||||||
x = x - 1
|
|
||||||
w = w + 1
|
|
||||||
end
|
|
||||||
-- this, in combination with 'forcefully blank out last column of window during render',
|
|
||||||
-- cleans up littering
|
|
||||||
w = w + 1
|
|
||||||
-- WCHAX: end
|
|
||||||
|
|
||||||
for span = 1, h do
|
|
||||||
local backgroundMarkStart = nil
|
|
||||||
for sx = 1, w do
|
|
||||||
local t, tx, ty = surfaceAt(monitorId, sx + x - 1, span + y - 1)
|
|
||||||
if t then
|
|
||||||
-- Background must occur first due to wide char weirdness
|
|
||||||
if backgroundMarkStart then
|
|
||||||
local bdx, bdy, bdl = backgroundMarkStart + x - 1, span + y - 1, sx - backgroundMarkStart
|
|
||||||
doBackgroundLine(m, mg, bdx, bdy, bdl)
|
|
||||||
backgroundMarkStart = nil
|
|
||||||
end
|
|
||||||
if not surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] then
|
|
||||||
surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] = true
|
|
||||||
surfaces[t][6]("line", ty)
|
|
||||||
end
|
|
||||||
elseif not backgroundMarkStart then
|
|
||||||
backgroundMarkStart = sx
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if backgroundMarkStart then
|
|
||||||
doBackgroundLine(monitors[monitorId], mg, backgroundMarkStart + x - 1, span + y - 1, (w - backgroundMarkStart) + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function updateStatus()
|
|
||||||
statusLine = "Λ-¶: menu (launch 'control' to logout)"
|
|
||||||
if surfaces[1] then
|
|
||||||
if #monitors > 1 then
|
|
||||||
-- 123456789X123456789X123456789X123456789X123456789X
|
|
||||||
statusLine = "Λ-+: move, Λ-Z: switch, Λ-X: swMonitor, Λ-C: close"
|
|
||||||
else
|
|
||||||
statusLine = "Λ-+: move, Λ-Z: switch, Λ-C: close"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
statusLine = unicode.safeTextFormat(statusLine)
|
|
||||||
for k, v in ipairs(monitors) do
|
|
||||||
updateRegion(k, 1, 1, v[3], 1, {})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ensureOnscreen(monitor, x, y, w, h)
|
|
||||||
if monitor <= 0 then monitor = #monitors end
|
|
||||||
if monitor >= (#monitors + 1) then monitor = 1 end
|
|
||||||
-- Failing anything else, revert to monitor 0
|
|
||||||
if #monitors == 0 then monitor = 0 end
|
|
||||||
x = math.min(math.max(1, x), monitors[monitor][3] - (w - 1))
|
|
||||||
y = math.max(1, math.min(monitors[monitor][4] - (h - 1), y))
|
|
||||||
return monitor, x, y
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This is the "a state change occurred" function, only for use when needed
|
|
||||||
local function reconcileAll()
|
|
||||||
for k, v in ipairs(surfaces) do
|
|
||||||
-- About to update whole screen anyway so avoid the wait.
|
|
||||||
v[1], v[2], v[3] = ensureOnscreen(v[1], v[2], v[3], v[4], v[5])
|
|
||||||
end
|
|
||||||
local k = 1
|
|
||||||
while k <= #monitors do
|
|
||||||
local v = monitors[k]
|
|
||||||
local mon, rb = v[1]()
|
|
||||||
if rb then
|
|
||||||
monitorResetBF(v)
|
|
||||||
end
|
|
||||||
if mon then
|
|
||||||
-- This *can* return null if something went wonky. Let's detect that
|
|
||||||
v[3], v[4] = mon.getResolution()
|
|
||||||
if not v[3] then
|
|
||||||
neo.emergency("everest: monitor went AWOL and nobody told me u.u")
|
|
||||||
table.remove(monitors, k)
|
|
||||||
v = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if v then
|
|
||||||
updateRegion(k, 1, 1, v[3], v[4], {})
|
|
||||||
k = k + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
updateStatus()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- NOTE: If the M, X, Y, W and H are the same, this function ignores you, unless you put , true on the end.
|
|
||||||
local function moveSurface(surface, m, x, y, w, h, force)
|
|
||||||
local om, ox, oy, ow, oh = table.unpack(surface, 1, 5)
|
|
||||||
m = m or om
|
|
||||||
x = x or ox
|
|
||||||
y = y or oy
|
|
||||||
w = w or ow
|
|
||||||
h = h or oh
|
|
||||||
surface[1], surface[2], surface[3], surface[4], surface[5] = m, x, y, w, h
|
|
||||||
local cache = {}
|
|
||||||
if om == m and ow == w and oh == h then
|
|
||||||
if ox == x and oy == y and not force then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- note: this doesn't always work due to WC support, and due to resize-to-repaint
|
|
||||||
if renderingAllowed() and not force then
|
|
||||||
local cb, b = monitors[m][1]()
|
|
||||||
if b then
|
|
||||||
monitorResetBF(monitors[m])
|
|
||||||
end
|
|
||||||
if cb then
|
|
||||||
pcall(cb.copy, ox, oy, w, h, x - ox, y - oy)
|
|
||||||
if surface == surfaces[1] then
|
|
||||||
local cacheControl = {}
|
|
||||||
for i = 1, h do
|
|
||||||
cacheControl[om .. "_1_" .. i] = true
|
|
||||||
end
|
|
||||||
updateRegion(om, ox, oy, ow, oh, cacheControl)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
updateRegion(om, ox, oy, ow, oh, cache)
|
|
||||||
updateRegion(m, x, y, w, h, cache)
|
|
||||||
end
|
|
||||||
-- Returns offset from where we expected to be to where we are.
|
|
||||||
local function ofsSurface(focus, dx, dy)
|
|
||||||
local exX, exY = focus[2] + dx, focus[3] + dy
|
|
||||||
local m, x, y = ensureOnscreen(focus[1], exX, exY, focus[4], focus[5])
|
|
||||||
moveSurface(focus, nil, x, y)
|
|
||||||
return focus[2] - exX, focus[3] - exY
|
|
||||||
end
|
|
||||||
local function ofsMSurface(focus, dm)
|
|
||||||
local m, x, y = ensureOnscreen(focus[1] + dm, focus[2], focus[3], focus[4], focus[5])
|
|
||||||
moveSurface(focus, m, x, y)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function handleSpan(target, x, y, text, bg, fg)
|
local function handleSpan(target, x, y, text, bg, fg)
|
||||||
if not renderingAllowed() then return end
|
if not renderingAllowed() then return end
|
||||||
local m = monitors[target[1]]
|
local m = monitors[target[1]]
|
||||||
@ -353,6 +210,178 @@ local function handleSpan(target, x, y, text, bg, fg)
|
|||||||
submitSegment()
|
submitSegment()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function updateRegion(monitorId, x, y, w, h, surfaceSpanCache)
|
||||||
|
if not renderingAllowed() then return end
|
||||||
|
local m = monitors[monitorId]
|
||||||
|
local mg, rb = m[1]()
|
||||||
|
if not mg then return end
|
||||||
|
if rb then
|
||||||
|
monitorResetBF(m)
|
||||||
|
end
|
||||||
|
-- The input region is the one that makes SENSE.
|
||||||
|
-- Considering WC handling, that's not an option.
|
||||||
|
-- WCHAX: start
|
||||||
|
if x > 1 then
|
||||||
|
x = x - 1
|
||||||
|
w = w + 1
|
||||||
|
end
|
||||||
|
-- this, in combination with 'forcefully blank out last column of window during render',
|
||||||
|
-- cleans up littering
|
||||||
|
w = w + 1
|
||||||
|
-- WCHAX: end
|
||||||
|
|
||||||
|
for span = 1, h do
|
||||||
|
local backgroundMarkStart = nil
|
||||||
|
for sx = 1, w do
|
||||||
|
local t, tx, ty = surfaceAt(monitorId, sx + x - 1, span + y - 1)
|
||||||
|
if t then
|
||||||
|
-- Background must occur first due to wide char weirdness
|
||||||
|
if backgroundMarkStart then
|
||||||
|
local bdx, bdy, bdl = backgroundMarkStart + x - 1, span + y - 1, sx - backgroundMarkStart
|
||||||
|
doBackgroundLine(m, mg, bdx, bdy, bdl)
|
||||||
|
backgroundMarkStart = nil
|
||||||
|
end
|
||||||
|
if not surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] then
|
||||||
|
surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] = true
|
||||||
|
if ty == 1 then
|
||||||
|
local lw = surfaces[t][4]
|
||||||
|
local bg = 0x0080FF
|
||||||
|
local fg = 0x000000
|
||||||
|
local tx = "-"
|
||||||
|
if t == 1 then
|
||||||
|
bg = 0x000000
|
||||||
|
fg = 0x0080FF
|
||||||
|
tx = "+"
|
||||||
|
end
|
||||||
|
local vtitle = surfaces[t][7]
|
||||||
|
local vto = unicode.len(vtitle)
|
||||||
|
if vto < lw then
|
||||||
|
vtitle = vtitle .. (tx):rep(lw - vto)
|
||||||
|
else
|
||||||
|
vtitle = unicode.sub(vtitle, 1, lw)
|
||||||
|
end
|
||||||
|
handleSpan(surfaces[t], 1, 1, vtitle, bg, fg)
|
||||||
|
else
|
||||||
|
surfaces[t][6](surfaces[t][8], "line", ty - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif not backgroundMarkStart then
|
||||||
|
backgroundMarkStart = sx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if backgroundMarkStart then
|
||||||
|
doBackgroundLine(monitors[monitorId], mg, backgroundMarkStart + x - 1, span + y - 1, (w - backgroundMarkStart) + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateStatus()
|
||||||
|
statusLine = "Λ-¶: menu (launch 'control' to logout)"
|
||||||
|
if surfaces[1] then
|
||||||
|
if #monitors > 1 then
|
||||||
|
-- 123456789X123456789X123456789X123456789X123456789X
|
||||||
|
statusLine = "Λ-+: move, Λ-Z: switch, Λ-X: swMonitor, Λ-C: close"
|
||||||
|
else
|
||||||
|
statusLine = "Λ-+: move, Λ-Z: switch, Λ-C: close"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
statusLine = unicode.safeTextFormat(statusLine)
|
||||||
|
for k, v in ipairs(monitors) do
|
||||||
|
updateRegion(k, 1, 1, v[3], 1, {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ensureOnscreen(monitor, x, y, w, h)
|
||||||
|
if monitor <= 0 then monitor = #monitors end
|
||||||
|
if monitor >= (#monitors + 1) then monitor = 1 end
|
||||||
|
-- Failing anything else, revert to monitor 0
|
||||||
|
if #monitors == 0 then monitor = 0 end
|
||||||
|
x = math.min(math.max(x, 1), monitors[monitor][3] - (w - 1))
|
||||||
|
y = math.max(2 - h, math.min(monitors[monitor][4], y))
|
||||||
|
return monitor, x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This is the "a state change occurred" function, only for use when needed
|
||||||
|
local function reconcileAll()
|
||||||
|
for k, v in ipairs(surfaces) do
|
||||||
|
-- About to update whole screen anyway so avoid the wait.
|
||||||
|
v[1], v[2], v[3] = ensureOnscreen(v[1], v[2], v[3], v[4], v[5])
|
||||||
|
end
|
||||||
|
local k = 1
|
||||||
|
while k <= #monitors do
|
||||||
|
local v = monitors[k]
|
||||||
|
local mon, rb = v[1]()
|
||||||
|
if rb then
|
||||||
|
monitorResetBF(v)
|
||||||
|
end
|
||||||
|
if mon then
|
||||||
|
-- This *can* return null if something went wonky. Let's detect that
|
||||||
|
v[3], v[4] = mon.getResolution()
|
||||||
|
if not v[3] then
|
||||||
|
neo.emergency("everest: monitor went AWOL and nobody told me u.u")
|
||||||
|
table.remove(monitors, k)
|
||||||
|
v = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if v then
|
||||||
|
updateRegion(k, 1, 1, v[3], v[4], {})
|
||||||
|
k = k + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
updateStatus()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- NOTE: If the M, X, Y, W and H are the same, this function ignores you, unless you put , true on the end.
|
||||||
|
local function moveSurface(surface, m, x, y, w, h, force)
|
||||||
|
local om, ox, oy, ow, oh = table.unpack(surface, 1, 5)
|
||||||
|
m = m or om
|
||||||
|
x = x or ox
|
||||||
|
y = y or oy
|
||||||
|
w = w or ow
|
||||||
|
h = h or oh
|
||||||
|
surface[1], surface[2], surface[3], surface[4], surface[5] = m, x, y, w, h
|
||||||
|
local cache = {}
|
||||||
|
if om == m and ow == w and oh == h then
|
||||||
|
if ox == x and oy == y and not force then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- note: this doesn't always work due to WC support, and due to resize-to-repaint
|
||||||
|
if renderingAllowed() and not force then
|
||||||
|
local cb, b = monitors[m][1]()
|
||||||
|
if b then
|
||||||
|
monitorResetBF(monitors[m])
|
||||||
|
end
|
||||||
|
if cb then
|
||||||
|
local monH = monitors[m][4]
|
||||||
|
local cutTop = math.max(0, 1 - math.min(oy, y))
|
||||||
|
local cutBottom = math.max(0, (math.max(oy + oh, y + h) - 1) - monH)
|
||||||
|
pcall(cb.copy, ox, oy + cutTop, w, h - (cutTop + cutBottom), x - ox, y - oy)
|
||||||
|
if surface == surfaces[1] then
|
||||||
|
local cacheControl = {}
|
||||||
|
for i = 1 + cutTop, h - cutBottom do
|
||||||
|
cacheControl[om .. "_1_" .. i] = true
|
||||||
|
end
|
||||||
|
updateRegion(om, ox, oy, ow, oh, cacheControl)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
updateRegion(om, ox, oy, ow, oh, cache)
|
||||||
|
updateRegion(m, x, y, w, h, cache)
|
||||||
|
end
|
||||||
|
-- Returns offset from where we expected to be to where we are.
|
||||||
|
local function ofsSurface(focus, dx, dy)
|
||||||
|
local exX, exY = focus[2] + dx, focus[3] + dy
|
||||||
|
local m, x, y = ensureOnscreen(focus[1], exX, exY, focus[4], focus[5])
|
||||||
|
moveSurface(focus, nil, x, y)
|
||||||
|
return focus[2] - exX, focus[3] - exY
|
||||||
|
end
|
||||||
|
local function ofsMSurface(focus, dm)
|
||||||
|
local m, x, y = ensureOnscreen(focus[1] + dm, focus[2], focus[3], focus[4], focus[5])
|
||||||
|
moveSurface(focus, m, x, y)
|
||||||
|
end
|
||||||
|
|
||||||
local basePalT2 = {
|
local basePalT2 = {
|
||||||
-- on T2 we provide 'system colours' by default
|
-- on T2 we provide 'system colours' by default
|
||||||
0x000000, 0x0080FF, 0x000040, 0xFFFFFF,
|
0x000000, 0x0080FF, 0x000040, 0xFFFFFF,
|
||||||
@ -416,11 +445,11 @@ local function changeFocus(oldSurface, optcache)
|
|||||||
if ns1 ~= oldSurface then
|
if ns1 ~= oldSurface then
|
||||||
if oldSurface then
|
if oldSurface then
|
||||||
setSurfacePalette(oldSurface, nil)
|
setSurfacePalette(oldSurface, nil)
|
||||||
oldSurface[6]("focus", false)
|
oldSurface[6](oldSurface[8], "focus", false)
|
||||||
end
|
end
|
||||||
if ns1 then
|
if ns1 then
|
||||||
setSurfacePalette(ns1, nil)
|
setSurfacePalette(ns1, nil)
|
||||||
ns1[6]("focus", true)
|
ns1[6](ns1[8], "focus", true)
|
||||||
end
|
end
|
||||||
updateStatus()
|
updateStatus()
|
||||||
if oldSurface then
|
if oldSurface then
|
||||||
@ -459,70 +488,11 @@ everestProvider(function (pkg, pid, sendSig)
|
|||||||
else
|
else
|
||||||
title = base .. ":" .. title
|
title = base .. ":" .. title
|
||||||
end
|
end
|
||||||
local surf = {math.min(#monitors, math.max(1, lIM)), 1, 2, w, h}
|
|
||||||
if h >= monitors[surf[1]][4] then
|
|
||||||
surf[3] = 1
|
|
||||||
end
|
|
||||||
local focusState = false
|
|
||||||
local llid = lid
|
local llid = lid
|
||||||
lid = lid + 1
|
lid = lid + 1
|
||||||
local specialDragHandler
|
local surf = {math.min(#monitors, math.max(1, lIM)), 1, 2, w, h, sendSig, title, llid}
|
||||||
surf[6] = function (ev, a, b, c, d, e)
|
if h >= monitors[surf[1]][4] then
|
||||||
-- Must forward surface events
|
surf[3] = 1
|
||||||
if ev == "focus" then
|
|
||||||
focusState = a
|
|
||||||
end
|
|
||||||
if ev == "touch" then
|
|
||||||
specialDragHandler = nil
|
|
||||||
if math.floor(b) == 1 then
|
|
||||||
if e == 1 then
|
|
||||||
sendSig(llid, "close")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
specialDragHandler = function (x, y)
|
|
||||||
local ofsX, ofsY = math.floor(x) - math.floor(a), math.floor(y) - math.floor(b)
|
|
||||||
if (ofsX == 0) and (ofsY == 0) then return end
|
|
||||||
ofsSurface(surf, ofsX, ofsY)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
b = b - 1
|
|
||||||
end
|
|
||||||
if ev == "drag" then
|
|
||||||
if specialDragHandler then
|
|
||||||
specialDragHandler(a, b)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
b = b - 1
|
|
||||||
end
|
|
||||||
if ev == "scroll" or ev == "drop" then
|
|
||||||
specialDragHandler = nil
|
|
||||||
b = b - 1
|
|
||||||
end
|
|
||||||
if ev == "line" then
|
|
||||||
if a == 1 then
|
|
||||||
local lw = surf[4]
|
|
||||||
local bg = 0x0080FF
|
|
||||||
local fg = 0x000000
|
|
||||||
local tx = "-"
|
|
||||||
if focusState then
|
|
||||||
bg = 0x000000
|
|
||||||
fg = 0x0080FF
|
|
||||||
tx = "+"
|
|
||||||
end
|
|
||||||
local vtitle = title
|
|
||||||
local vto = unicode.len(vtitle)
|
|
||||||
if vto < lw then
|
|
||||||
vtitle = vtitle .. (tx):rep(lw - vto)
|
|
||||||
else
|
|
||||||
vtitle = unicode.sub(vtitle, 1, lw)
|
|
||||||
end
|
|
||||||
handleSpan(surf, 1, 1, vtitle, bg, fg)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
a = a - 1
|
|
||||||
end
|
|
||||||
sendSig(llid, ev, a, b, c, d, e)
|
|
||||||
end
|
end
|
||||||
local osrf = surfaces[1]
|
local osrf = surfaces[1]
|
||||||
table.insert(surfaces, 1, surf)
|
table.insert(surfaces, 1, surf)
|
||||||
@ -551,17 +521,13 @@ everestProvider(function (pkg, pid, sendSig)
|
|||||||
end,
|
end,
|
||||||
span = function (x, y, text, bg, fg)
|
span = function (x, y, text, bg, fg)
|
||||||
if neo.dead then error("everest died") end
|
if neo.dead then error("everest died") end
|
||||||
if type(x) ~= "number" then error("X must be number.") end
|
checkArg(3, text, "string")
|
||||||
if type(y) ~= "number" then error("Y must be number.") end
|
|
||||||
if type(bg) ~= "number" then error("Background must be number.") end
|
|
||||||
if type(fg) ~= "number" then error("Foreground must be number.") end
|
|
||||||
if type(text) ~= "string" then error("Text must be string.") end
|
|
||||||
x, y, bg, fg = math.floor(x), math.floor(y), math.floor(bg), math.floor(fg)
|
x, y, bg, fg = math.floor(x), math.floor(y), math.floor(bg), math.floor(fg)
|
||||||
if y == 0 then return end
|
if y == 0 then return end
|
||||||
handleSpan(surf, x, y + 1, text, bg, fg)
|
handleSpan(surf, x, y + 1, text, bg, fg)
|
||||||
end,
|
end,
|
||||||
recommendPalette = function (pal)
|
recommendPalette = function (pal)
|
||||||
if not focusState then return 0 end
|
if surfaces[1] ~= surf then return 0 end
|
||||||
return setSurfacePalette(surf, pal)
|
return setSurfacePalette(surf, pal)
|
||||||
end,
|
end,
|
||||||
close = function ()
|
close = function ()
|
||||||
@ -586,7 +552,7 @@ end)
|
|||||||
-- THE EVEREST USER API ENDS (now for the session API, which just does boring stuff)
|
-- THE EVEREST USER API ENDS (now for the session API, which just does boring stuff)
|
||||||
-- used later on for lost monitor, too
|
-- used later on for lost monitor, too
|
||||||
local function disclaimMonitor(mon)
|
local function disclaimMonitor(mon)
|
||||||
neo.ensureType(mon, "string")
|
checkArg(1, mon, "string")
|
||||||
screens.disclaim(mon)
|
screens.disclaim(mon)
|
||||||
for k, v in ipairs(monitors) do
|
for k, v in ipairs(monitors) do
|
||||||
if v[2] == mon then
|
if v[2] == mon then
|
||||||
@ -600,7 +566,7 @@ end
|
|||||||
everestSessionProvider(function (pkg, pid, sendSig)
|
everestSessionProvider(function (pkg, pid, sendSig)
|
||||||
return {
|
return {
|
||||||
endSession = function (gotoBristol)
|
endSession = function (gotoBristol)
|
||||||
neo.ensureType(gotoBristol, "boolean")
|
checkArg(1, gotoBristol, "boolean")
|
||||||
shuttingDown = true
|
shuttingDown = true
|
||||||
if gotoBristol then
|
if gotoBristol then
|
||||||
suggestAppsStop()
|
suggestAppsStop()
|
||||||
@ -638,69 +604,59 @@ end
|
|||||||
local isAltDown = false
|
local isAltDown = false
|
||||||
local isCtrDown = false
|
local isCtrDown = false
|
||||||
local function key(ku, ka, kc, down)
|
local function key(ku, ka, kc, down)
|
||||||
local ku = screens.getMonitorByKeyboard(ku)
|
local ku, lin = screens.getMonitorByKeyboard(ku)
|
||||||
if not ku then return end
|
|
||||||
for k, v in ipairs(monitors) do
|
for k, v in ipairs(monitors) do
|
||||||
if v[2] == mu then
|
if ku and v[2] == ku then
|
||||||
lIM = k
|
lin = k
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if not lin then return end
|
||||||
|
lIM = lin
|
||||||
|
|
||||||
local focus = surfaces[1]
|
local focus = surfaces[1]
|
||||||
if kc == 29 then isCtrDown = down end
|
if kc == 29 then
|
||||||
if kc == 56 then isAltDown = down end
|
isCtrDown = down
|
||||||
if isAltDown then
|
elseif kc == 56 then
|
||||||
if ka == 120 then
|
isAltDown = down
|
||||||
if focus and down then ofsMSurface(focus, 1) end return
|
end
|
||||||
|
if isAltDown and ka == 122 then
|
||||||
|
if focus and down then
|
||||||
|
local n = table.remove(surfaces, 1)
|
||||||
|
table.insert(surfaces, n)
|
||||||
|
changeFocus(n)
|
||||||
end
|
end
|
||||||
if kc == 200 then
|
elseif isAltDown and kc == 200 then
|
||||||
if focus and down then ofsSurface(focus, 0, -1) end return
|
if focus and down then ofsSurface(focus, 0, -1) end
|
||||||
|
elseif isAltDown and kc == 208 then
|
||||||
|
if focus and down then ofsSurface(focus, 0, 1) end
|
||||||
|
elseif isAltDown and kc == 203 then
|
||||||
|
if focus and down then ofsSurface(focus, -1, 0) end
|
||||||
|
elseif isAltDown and kc == 205 then
|
||||||
|
if focus and down then ofsSurface(focus, 1, 0) end
|
||||||
|
elseif isAltDown and ka == 120 then
|
||||||
|
if focus and down then ofsMSurface(focus, 1) end
|
||||||
|
elseif isAltDown and ka == 97 then
|
||||||
|
if not down then
|
||||||
|
isAltDown = false
|
||||||
end
|
end
|
||||||
if kc == 208 then
|
elseif isAltDown and (ka == 3 or ka == 99) then
|
||||||
if focus and down then ofsSurface(focus, 0, 1) end return
|
if down then
|
||||||
end
|
|
||||||
if kc == 203 then
|
|
||||||
if focus and down then ofsSurface(focus, -1, 0) end return
|
|
||||||
end
|
|
||||||
if kc == 205 then
|
|
||||||
if focus and down then ofsSurface(focus, 1, 0) end return
|
|
||||||
end
|
|
||||||
if ka == 122 then
|
|
||||||
if focus and down then
|
|
||||||
local n = table.remove(surfaces, 1)
|
|
||||||
table.insert(surfaces, n)
|
|
||||||
changeFocus(n)
|
|
||||||
end return
|
|
||||||
end
|
|
||||||
if ka == 3 then
|
|
||||||
-- Ctrl-Alt-C (!?!?!!)
|
|
||||||
if isCtrDown then
|
if isCtrDown then
|
||||||
error("User-authorized Everest crash.")
|
error("User-authorized Everest crash.")
|
||||||
|
elseif focus then
|
||||||
|
focus[6](focus[8], "close")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if ka == 99 then
|
elseif isAltDown and ka == 13 then
|
||||||
if down then
|
if down then
|
||||||
if isCtrDown then
|
startLauncher()
|
||||||
error("User-authorized Everest crash.")
|
|
||||||
else
|
|
||||||
if focus then
|
|
||||||
focus[6]("close")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
if ka == 13 then
|
elseif focus then
|
||||||
if down then
|
|
||||||
startLauncher()
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if focus then
|
|
||||||
if kc ~= 56 then
|
if kc ~= 56 then
|
||||||
lIM = focus[1]
|
lIM = focus[1]
|
||||||
end
|
end
|
||||||
focus[6]("key", ka, kc, down)
|
focus[6](focus[8], "key", ka, kc, down)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -733,7 +689,7 @@ while not shuttingDown do
|
|||||||
end
|
end
|
||||||
if s[1] == "h.clipboard" then
|
if s[1] == "h.clipboard" then
|
||||||
if surfaces[1] then
|
if surfaces[1] then
|
||||||
surfaces[1][6]("clipboard", s[3])
|
surfaces[1][6](surfaces[1][8], "clipboard", s[3])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- next on my list: high-res coordinates
|
-- next on my list: high-res coordinates
|
||||||
@ -749,7 +705,16 @@ while not shuttingDown do
|
|||||||
local ns = table.remove(surfaces, sid)
|
local ns = table.remove(surfaces, sid)
|
||||||
table.insert(surfaces, 1, ns)
|
table.insert(surfaces, 1, ns)
|
||||||
changeFocus(os)
|
changeFocus(os)
|
||||||
ns[6]("touch", lx, ly, ix, iy, s[5])
|
draggingWindowX, draggingWindowY = nil
|
||||||
|
if ly == 1 then
|
||||||
|
if s[5] == 1 then
|
||||||
|
ns[6](ns[8], "close")
|
||||||
|
else
|
||||||
|
draggingWindowX, draggingWindowY = lx, ly
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ns[6](ns[8], "touch", lx, ly - 1, ix, iy, s[5])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if s[5] == 1 then startLauncher() end
|
if s[5] == 1 then startLauncher() end
|
||||||
end
|
end
|
||||||
@ -766,8 +731,16 @@ while not shuttingDown do
|
|||||||
if k == focus[1] then
|
if k == focus[1] then
|
||||||
local x, y = (math.ceil(s[3]) - focus[2]) + 1, (math.ceil(s[4]) - focus[3]) + 1
|
local x, y = (math.ceil(s[3]) - focus[2]) + 1, (math.ceil(s[4]) - focus[3]) + 1
|
||||||
local ix, iy = s[3] - math.floor(s[3]), s[4] - math.floor(s[4])
|
local ix, iy = s[3] - math.floor(s[3]), s[4] - math.floor(s[4])
|
||||||
-- Ok, so let's see...
|
if s[1] == "h.drag" and draggingWindowX then
|
||||||
focus[6](s[1]:sub(3), x, y, ix, iy, s[5])
|
local ofsX, ofsY = x - draggingWindowX, y - draggingWindowY
|
||||||
|
if ofsX ~= 0 or ofsY ~= 0 then
|
||||||
|
ofsSurface(focus, ofsX, ofsY)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
draggingWindowX, draggingWindowY = nil
|
||||||
|
-- Ok, so let's see...
|
||||||
|
focus[6](focus[8], s[1]:sub(3), x, y - 1, ix, iy, s[5])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -799,7 +772,7 @@ while not shuttingDown do
|
|||||||
if os1 then
|
if os1 then
|
||||||
changeFocus(os1)
|
changeFocus(os1)
|
||||||
else
|
else
|
||||||
changeFocus(surfaces[1])
|
changeFocus()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if s[1] == "x.neo.sys.screens" then
|
if s[1] == "x.neo.sys.screens" then
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- s-donkonit : config, shutdown, screens
|
-- s-donkonit : config, shutdown, screens
|
||||||
|
|
||||||
@ -125,7 +129,7 @@ local mBase = {
|
|||||||
end
|
end
|
||||||
return s
|
return s
|
||||||
end,
|
end,
|
||||||
delSetting = function ()
|
delSetting = function (name)
|
||||||
neo.ensureType(name, "string")
|
neo.ensureType(name, "string")
|
||||||
local val = nil
|
local val = nil
|
||||||
if name == "password" or name == "pub.clipboard" then val = "" end
|
if name == "password" or name == "pub.clipboard" then val = "" end
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- s-icecap : Responsible for x.neo.pub API, crash dialogs, and security policy that isn't "sys- has ALL access, anything else has none"
|
-- s-icecap : Responsible for x.neo.pub API, crash dialogs, and security policy that isn't "sys- has ALL access, anything else has none"
|
||||||
-- In general, this is what userspace will be interacting with in some way or another to get stuff done
|
-- In general, this is what userspace will be interacting with in some way or another to get stuff done
|
||||||
@ -81,20 +85,12 @@ local function getPfx(xd, pkg)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local endAcPattern = "/[a-z0-9/%.]*$"
|
local function splitAC(ac)
|
||||||
|
local sb = ac:match("/[a-z0-9/%.]*$")
|
||||||
local function matchesSvc(xd, pkg, perm)
|
if sb then
|
||||||
local pfx = getPfx(xd, pkg)
|
return ac:sub(1, #ac - #sb), sb
|
||||||
if pfx then
|
|
||||||
local permAct = perm
|
|
||||||
local paP = permAct:match(endAcPattern)
|
|
||||||
if paP then
|
|
||||||
permAct = permAct:sub(1, #permAct - #paP)
|
|
||||||
end
|
|
||||||
if permAct == pfx then
|
|
||||||
return "allow"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
return ac
|
||||||
end
|
end
|
||||||
|
|
||||||
donkonitDFProvider(function (pkg, pid, sendSig)
|
donkonitDFProvider(function (pkg, pid, sendSig)
|
||||||
@ -109,17 +105,20 @@ donkonitDFProvider(function (pkg, pid, sendSig)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return {
|
return {
|
||||||
showFileDialogAsync = function (forWrite)
|
showFileDialogAsync = function (forWrite, defName)
|
||||||
if not rawequal(forWrite, nil) then
|
if not rawequal(forWrite, nil) then
|
||||||
require("sys-filewrap").ensureMode(forWrite)
|
require("sys-filewrap").ensureMode(forWrite)
|
||||||
end
|
end
|
||||||
|
if not rawequal(defName, nil) then
|
||||||
|
defName = tostring(defName)
|
||||||
|
end
|
||||||
-- Not hooked into the event API, so can't safely interfere
|
-- Not hooked into the event API, so can't safely interfere
|
||||||
-- Thus, this is async and uses a return event.
|
-- Thus, this is async and uses a return event.
|
||||||
local tag = {}
|
local tag = {}
|
||||||
neo.scheduleTimer(0)
|
neo.scheduleTimer(0)
|
||||||
table.insert(todo, function ()
|
table.insert(todo, function ()
|
||||||
-- sys-filedialog is yet another "library to control memory usage".
|
-- sys-filedialog is yet another "library to control memory usage".
|
||||||
local closer = require("sys-filedialog")(event, nexus, function (res) openHandles[tag] = nil sendSig("filedialog", tag, res) end, neo.requireAccess("c.filesystem", "file managers"), pkg, forWrite)
|
local closer = require("sys-filedialog")(event, nexus, function (res) openHandles[tag] = nil sendSig("filedialog", tag, res) end, neo.requireAccess("c.filesystem", "file managers"), pkg, forWrite, defName)
|
||||||
openHandles[tag] = closer
|
openHandles[tag] = closer
|
||||||
end)
|
end)
|
||||||
return tag
|
return tag
|
||||||
@ -127,7 +126,8 @@ donkonitDFProvider(function (pkg, pid, sendSig)
|
|||||||
myApi = getPfx("", pkg),
|
myApi = getPfx("", pkg),
|
||||||
lockPerm = function (perm)
|
lockPerm = function (perm)
|
||||||
-- Are we allowed to?
|
-- Are we allowed to?
|
||||||
if not matchesSvc("x.", pkg, perm) then
|
local permPfx, detail = splitAC(perm)
|
||||||
|
if getPfx("x.", pkg) ~= permPfx then
|
||||||
return false, "You don't own this permission."
|
return false, "You don't own this permission."
|
||||||
end
|
end
|
||||||
local set = "perm|*|" .. perm
|
local set = "perm|*|" .. perm
|
||||||
@ -220,7 +220,11 @@ local function secPolicyStage2(pid, proc, perm, req)
|
|||||||
-- Push to ICECAP thread to avoid deadlock b/c wrong event-pull context
|
-- Push to ICECAP thread to avoid deadlock b/c wrong event-pull context
|
||||||
neo.scheduleTimer(0)
|
neo.scheduleTimer(0)
|
||||||
table.insert(todo, function ()
|
table.insert(todo, function ()
|
||||||
local ok, err = pcall(secpol, nexus, settings, proc.pkg, pid, perm, req, matchesSvc)
|
local fPerm = perm
|
||||||
|
if fPerm:sub(1, 2) == "r." then
|
||||||
|
fPerm = splitAC(fPerm)
|
||||||
|
end
|
||||||
|
local ok, err = pcall(secpol, nexus, settings, proc.pkg, pid, fPerm, req, getPfx("", proc.pkg))
|
||||||
if not ok then
|
if not ok then
|
||||||
neo.emergency("Used fallback policy because of run-err: " .. err)
|
neo.emergency("Used fallback policy because of run-err: " .. err)
|
||||||
req(def)
|
req(def)
|
||||||
@ -240,11 +244,7 @@ rootAccess.securityPolicy = function (pid, proc, perm, req)
|
|||||||
end
|
end
|
||||||
-- Do we need to start it?
|
-- Do we need to start it?
|
||||||
if perm:sub(1, 6) == "x.svc." and not neo.usAccessExists(perm) then
|
if perm:sub(1, 6) == "x.svc." and not neo.usAccessExists(perm) then
|
||||||
local appAct = perm:sub(7)
|
local appAct = splitAC(perm:sub(7))
|
||||||
local paP = appAct:match(endAcPattern)
|
|
||||||
if paP then
|
|
||||||
appAct = appAct:sub(1, #appAct - #paP)
|
|
||||||
end
|
|
||||||
-- Prepare for success
|
-- Prepare for success
|
||||||
onReg[perm] = onReg[perm] or {}
|
onReg[perm] = onReg[perm] or {}
|
||||||
local orp = onReg[perm]
|
local orp = onReg[perm]
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- s-bristol splash screen, login agent
|
-- s-bristol splash screen, login agent
|
||||||
-- Named to allude to Plymouth (splash screen used in some linux distros)
|
-- Named to allude to Plymouth (splash screen used in some linux distros)
|
||||||
|
|
||||||
local callerPkg, callerPid, callerScr = ...
|
local callerPkg, callerPid, callerScr = ...
|
||||||
|
|
||||||
local gpuG, screen = nil, nil
|
|
||||||
local shutdownEmergency = neo.requestAccess("k.computer").shutdown
|
local shutdownEmergency = neo.requestAccess("k.computer").shutdown
|
||||||
neo.requestAccess("s.h.key_down")
|
neo.requestAccess("s.h.key_down")
|
||||||
|
neo.requestAccess("s.h._kosneo_syslog")
|
||||||
|
|
||||||
local scrW, scrH
|
-- gpuG/performDisclaim are GPU management, while screen is used for prioritization
|
||||||
local warnings = {
|
local gpuG, performDisclaim, screen = nil
|
||||||
"",
|
local scrW, scrH = 1, 1
|
||||||
"",
|
local nssInst
|
||||||
""
|
|
||||||
}
|
local console = {}
|
||||||
|
local helpActive = false
|
||||||
|
local buttonsActive = false
|
||||||
|
|
||||||
-- Attempts to call upon nsm for a safe shutdown
|
-- Attempts to call upon nsm for a safe shutdown
|
||||||
local function shutdown(reboot)
|
local function shutdown(reboot)
|
||||||
@ -30,32 +36,53 @@ local function shutdown(reboot)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function rstfbDraw(gpu)
|
local function basicDraw(bg)
|
||||||
pcall(gpu.setBackground, 0xFFFFFF)
|
local gpu = gpuG()
|
||||||
|
pcall(gpu.setBackground, bg or 0xFFFFFF)
|
||||||
pcall(gpu.setForeground, 0x000000)
|
pcall(gpu.setForeground, 0x000000)
|
||||||
end
|
|
||||||
|
|
||||||
local function basicDraw(gpu)
|
|
||||||
local ok, sw, sh = pcall(gpu.getResolution)
|
local ok, sw, sh = pcall(gpu.getResolution)
|
||||||
if not ok then return end
|
if not ok then return end
|
||||||
scrW, scrH = sw, sh
|
scrW, scrH = sw, sh
|
||||||
pcall(gpu.fill, 1, 1, scrW, scrH, " ")
|
pcall(gpu.fill, 1, 1, scrW, scrH, " ")
|
||||||
pcall(gpu.set, 2, 2, "KittenOS NEO")
|
pcall(gpu.set, 2, 2, "KittenOS NEO")
|
||||||
end
|
|
||||||
|
|
||||||
local function advDraw(gpu)
|
|
||||||
basicDraw(gpu)
|
|
||||||
local usage = math.floor((os.totalMemory() - os.freeMemory()) / 1024)
|
local usage = math.floor((os.totalMemory() - os.freeMemory()) / 1024)
|
||||||
pcall(gpu.set, 2, 3, "RAM Usage: " .. usage .. "K / " .. math.floor(os.totalMemory() / 1024) .. "K")
|
pcall(gpu.set, 2, 3, "RAM Usage: " .. usage .. "K / " .. math.floor(os.totalMemory() / 1024) .. "K")
|
||||||
for i = 1, #warnings do
|
local cut = 7
|
||||||
pcall(gpu.set, 2, 6 + i, warnings[i])
|
if buttonsActive then cut = 9 end
|
||||||
|
local areaSize = scrH - cut
|
||||||
|
local n2 = 0
|
||||||
|
if helpActive then
|
||||||
|
if _VERSION == "Lua 5.2" then
|
||||||
|
table.insert(console, "WARNING: Lua 5.2 memory usage issue!")
|
||||||
|
table.insert(console, "Shift-right-click while holding the CPU/APU.")
|
||||||
|
n2 = 2
|
||||||
|
end
|
||||||
|
table.insert(console, "TAB to change option, ENTER to select.")
|
||||||
|
n2 = n2 + 1
|
||||||
|
end
|
||||||
|
for i = 1, areaSize do
|
||||||
|
pcall(gpu.set, 2, 6 + i, console[#console + i - areaSize] or "")
|
||||||
|
end
|
||||||
|
for i = 1, n2 do
|
||||||
|
table.remove(console, #console)
|
||||||
|
end
|
||||||
|
return gpu
|
||||||
|
end
|
||||||
|
|
||||||
|
local function consoleEventHandler(ev)
|
||||||
|
if ev[1] == "h._kosneo_syslog" then
|
||||||
|
local text = ""
|
||||||
|
for i = 3, #ev do
|
||||||
|
if i ~= 3 then text = text .. " " end
|
||||||
|
text = text .. tostring(ev[i])
|
||||||
|
end
|
||||||
|
table.insert(console, text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Callback setup by finalPrompt to disclaim the main monitor first
|
-- Attempts to get an NSS monitor with a priority list of screens
|
||||||
local performDisclaim = nil
|
local function retrieveNssMonitor(...)
|
||||||
|
local spc = {...}
|
||||||
local function retrieveNssMonitor(nss)
|
|
||||||
gpuG = nil
|
gpuG = nil
|
||||||
local subpool = {}
|
local subpool = {}
|
||||||
while not gpuG do
|
while not gpuG do
|
||||||
@ -67,19 +94,23 @@ local function retrieveNssMonitor(nss)
|
|||||||
-- If no monitors are available, shut down now.
|
-- If no monitors are available, shut down now.
|
||||||
-- NSS monitor pool output is smaller than, but similar to, Everest monitor data:
|
-- NSS monitor pool output is smaller than, but similar to, Everest monitor data:
|
||||||
-- {gpu, screenAddr}
|
-- {gpu, screenAddr}
|
||||||
local pool = nss.getClaimable()
|
local pool = nssInst.getClaimable()
|
||||||
while not pool[1] do
|
while not pool[1] do
|
||||||
coroutine.yield() -- wait for presumably a NSS notification
|
-- wait for presumably a NSS notification
|
||||||
pool = nss.getClaimable()
|
consoleEventHandler({coroutine.yield()})
|
||||||
|
pool = nssInst.getClaimable()
|
||||||
end
|
end
|
||||||
subpool = {}
|
subpool = {}
|
||||||
-- Specifies which element to elevate to top priority
|
-- Specifies which element to elevate to top priority
|
||||||
local optimalSwap = nil
|
local optimalSwap = nil
|
||||||
|
local optimal = #spc + 1
|
||||||
if screen then
|
if screen then
|
||||||
for k, v in ipairs(pool) do
|
for k, v in ipairs(pool) do
|
||||||
if v == screen then
|
for k2, v2 in ipairs(spc) do
|
||||||
optimalSwap = k
|
if v == v2 and optimal > k2 then
|
||||||
break
|
optimalSwap, optimal = k, k2
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -89,7 +120,7 @@ local function retrieveNssMonitor(nss)
|
|||||||
pool[1] = swapA
|
pool[1] = swapA
|
||||||
end
|
end
|
||||||
for _, v in ipairs(pool) do
|
for _, v in ipairs(pool) do
|
||||||
local gpu = nss.claim(v)
|
local gpu = nssInst.claim(v)
|
||||||
if gpu then
|
if gpu then
|
||||||
local gcb = gpu()
|
local gcb = gpu()
|
||||||
if gcb then
|
if gcb then
|
||||||
@ -102,52 +133,53 @@ local function retrieveNssMonitor(nss)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if subpool[1] then
|
||||||
if not subpool[1] then
|
gpuG, screen = table.unpack(subpool[1])
|
||||||
error("None of the GPUs we got were actually usable")
|
|
||||||
end
|
end
|
||||||
gpuG = subpool[1][1]
|
|
||||||
screen = subpool[1][2]
|
|
||||||
end
|
end
|
||||||
-- done with search
|
-- done with search
|
||||||
local gpu = gpuG()
|
|
||||||
rstfbDraw(gpu)
|
|
||||||
performDisclaim = function (full)
|
performDisclaim = function (full)
|
||||||
nss.disclaim(subpool[1][2])
|
nssInst.disclaim(subpool[1][2])
|
||||||
if full then
|
if full then
|
||||||
for _, v in ipairs(subpool) do
|
for _, v in ipairs(subpool) do
|
||||||
nss.disclaim(v[2])
|
nssInst.disclaim(v[2])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return gpu
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sleep(t)
|
local function sleep(t)
|
||||||
neo.scheduleTimer(os.uptime() + t)
|
neo.scheduleTimer(os.uptime() + t)
|
||||||
while true do
|
while true do
|
||||||
local ev = {coroutine.yield()}
|
local ev = {coroutine.yield()}
|
||||||
|
consoleEventHandler(ev)
|
||||||
if ev[1] == "k.timer" then
|
if ev[1] == "k.timer" then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if ev[1] == "x.neo.sys.screens" then
|
if ev[1] == "x.neo.sys.screens" then
|
||||||
-- This implies we have and can use nss, but check anyway
|
retrieveNssMonitor(screen)
|
||||||
local nss = neo.requestAccess("x.neo.sys.screens")
|
basicDraw()
|
||||||
if nss then
|
|
||||||
local gpu = retrieveNssMonitor(nss)
|
|
||||||
basicDraw(gpu)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function alert(s)
|
||||||
|
console = {s}
|
||||||
|
helpActive, buttonsActive = false, false
|
||||||
|
basicDraw()
|
||||||
|
sleep(1)
|
||||||
|
buttonsActive = true
|
||||||
|
end
|
||||||
|
|
||||||
local function finalPrompt()
|
local function finalPrompt()
|
||||||
local nss = neo.requestAccess("x.neo.sys.screens")
|
nssInst = neo.requestAccess("x.neo.sys.screens")
|
||||||
if nss then
|
if not nssInst then
|
||||||
retrieveNssMonitor(nss)
|
console = {"sys-glacier not available"}
|
||||||
else
|
basicDraw()
|
||||||
error("no glacier to provide GPU for the prompt")
|
error("no nssInst")
|
||||||
end
|
end
|
||||||
|
retrieveNssMonitor()
|
||||||
|
helpActive, buttonsActive = true, true
|
||||||
-- This is nsm's final chance to make itself available and thus allow the password to be set
|
-- This is nsm's final chance to make itself available and thus allow the password to be set
|
||||||
local nsm = neo.requestAccess("x.neo.sys.manage")
|
local nsm = neo.requestAccess("x.neo.sys.manage")
|
||||||
local waiting = true
|
local waiting = true
|
||||||
@ -159,24 +191,11 @@ local function finalPrompt()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if _VERSION == "Lua 5.2" then
|
|
||||||
warnings[1] = "NOTE: It's recommended you use Lua 5.3."
|
|
||||||
warnings[2] = "Shift-right-click while holding the CPU item."
|
|
||||||
else
|
|
||||||
warnings[1] = "TAB to change option,"
|
|
||||||
warnings[2] = "ENTER to select..."
|
|
||||||
end
|
|
||||||
-- The actual main prompt loop
|
-- The actual main prompt loop
|
||||||
while waiting do
|
while waiting do
|
||||||
local gpu = gpuG()
|
|
||||||
rstfbDraw(gpu)
|
|
||||||
advDraw(gpu)
|
|
||||||
local entry = ""
|
local entry = ""
|
||||||
local entry2 = ""
|
local entry2 = ""
|
||||||
local active = true
|
local active = true
|
||||||
local shButton = "<Shutdown>"
|
|
||||||
local rbButton = "<Reboot>"
|
|
||||||
local smButton = "<Safe Mode>"
|
|
||||||
local pw = {function ()
|
local pw = {function ()
|
||||||
return "Password: " .. entry2
|
return "Password: " .. entry2
|
||||||
end, function (key)
|
end, function (key)
|
||||||
@ -188,10 +207,7 @@ local function finalPrompt()
|
|||||||
if entry == password then
|
if entry == password then
|
||||||
waiting = false
|
waiting = false
|
||||||
else
|
else
|
||||||
local gpu = gpuG()
|
alert("Incorrect password")
|
||||||
rstfbDraw(gpu)
|
|
||||||
advDraw(gpu)
|
|
||||||
sleep(1)
|
|
||||||
end
|
end
|
||||||
active = false
|
active = false
|
||||||
end
|
end
|
||||||
@ -208,68 +224,69 @@ local function finalPrompt()
|
|||||||
end
|
end
|
||||||
local controls = {
|
local controls = {
|
||||||
{function ()
|
{function ()
|
||||||
return shButton
|
return "<Shutdown>"
|
||||||
end, function (key)
|
end, function (key)
|
||||||
if key == 13 then
|
if key == 13 then
|
||||||
local gpu = gpuG()
|
alert("Shutting down...")
|
||||||
rstfbDraw(gpu)
|
|
||||||
basicDraw(gpu)
|
|
||||||
pcall(gpu.set, 2, 4, "Shutting down...")
|
|
||||||
shutdown(false)
|
shutdown(false)
|
||||||
end
|
end
|
||||||
end, 2, scrH - 1, unicode.len(shButton)},
|
end, 2, scrH - 1, 10},
|
||||||
{function ()
|
{function ()
|
||||||
return rbButton
|
return "<Reboot>"
|
||||||
end, function (key)
|
end, function (key)
|
||||||
if key == 13 then
|
if key == 13 then
|
||||||
local gpu = gpuG()
|
alert("Rebooting...")
|
||||||
rstfbDraw(gpu)
|
|
||||||
basicDraw(gpu)
|
|
||||||
pcall(gpu.set, 2, 4, "Rebooting...")
|
|
||||||
shutdown(true)
|
shutdown(true)
|
||||||
end
|
end
|
||||||
end, 3 + unicode.len(shButton), scrH - 1, unicode.len(rbButton)},
|
end, 13, scrH - 1, 8},
|
||||||
{function ()
|
{function ()
|
||||||
return smButton
|
return "<Safe Mode>"
|
||||||
end, function (key)
|
end, function (key)
|
||||||
if key == 13 then
|
if key == 13 then
|
||||||
local gpu = gpuG()
|
|
||||||
rstfbDraw(gpu)
|
|
||||||
basicDraw(gpu)
|
|
||||||
pcall(gpu.set, 2, 4, "Login to activate Safe Mode.")
|
|
||||||
sleep(1)
|
|
||||||
gpu = gpuG()
|
|
||||||
safeModeActive = true
|
safeModeActive = true
|
||||||
rstfbDraw(gpu)
|
alert("Login to activate Safe Mode.")
|
||||||
advDraw(gpu)
|
|
||||||
end
|
end
|
||||||
end, 4 + unicode.len(shButton) + unicode.len(rbButton), scrH - 1, unicode.len(smButton)},
|
end, 22, scrH - 1, 11},
|
||||||
pw,
|
pw,
|
||||||
}
|
}
|
||||||
local control = #controls
|
local control = #controls
|
||||||
|
local lastKeyboard
|
||||||
while active do
|
while active do
|
||||||
local gpu = gpuG()
|
local gpu = basicDraw()
|
||||||
for k, v in ipairs(controls) do
|
if gpu then
|
||||||
if k == control then
|
for k, v in ipairs(controls) do
|
||||||
pcall(gpu.setBackground, 0x000000)
|
if k == control then
|
||||||
pcall(gpu.setForeground, 0xFFFFFF)
|
pcall(gpu.setBackground, 0x000000)
|
||||||
else
|
pcall(gpu.setForeground, 0xFFFFFF)
|
||||||
pcall(gpu.setBackground, 0xFFFFFF)
|
else
|
||||||
pcall(gpu.setForeground, 0x000000)
|
pcall(gpu.setBackground, 0xFFFFFF)
|
||||||
|
pcall(gpu.setForeground, 0x000000)
|
||||||
|
end
|
||||||
|
pcall(gpu.fill, v[3], v[4], v[5], 1, " ")
|
||||||
|
pcall(gpu.set, v[3], v[4], v[1]())
|
||||||
end
|
end
|
||||||
pcall(gpu.fill, v[3], v[4], v[5], 1, " ")
|
|
||||||
pcall(gpu.set, v[3], v[4], v[1]())
|
|
||||||
end
|
end
|
||||||
-- event handling...
|
-- event handling...
|
||||||
local sig = {coroutine.yield()}
|
local sig = {coroutine.yield()}
|
||||||
|
consoleEventHandler(sig)
|
||||||
if sig[1] == "x.neo.sys.screens" then
|
if sig[1] == "x.neo.sys.screens" then
|
||||||
-- We need to reinit screens no matter what.
|
-- We need to reinit screens no matter what.
|
||||||
retrieveNssMonitor(nss)
|
retrieveNssMonitor(screen)
|
||||||
|
active = false
|
||||||
end
|
end
|
||||||
if sig[1] == "h.key_down" then
|
if sig[1] == "h.key_down" then
|
||||||
|
if sig[2] ~= lastKeyboard then
|
||||||
|
lastKeyboard = sig[2]
|
||||||
|
local nScreen = nssInst.getMonitorByKeyboard(lastKeyboard)
|
||||||
|
if nScreen and nScreen ~= screen then
|
||||||
|
neo.emergency("new primary:", nScreen)
|
||||||
|
retrieveNssMonitor(nScreen, screen)
|
||||||
|
active = false
|
||||||
|
end
|
||||||
|
end
|
||||||
if sig[4] == 15 then
|
if sig[4] == 15 then
|
||||||
-- this makes sense in context
|
-- this makes sense in context
|
||||||
control = control % (#controls)
|
control = control % #controls
|
||||||
control = control + 1
|
control = control + 1
|
||||||
else
|
else
|
||||||
controls[control][2](sig[3])
|
controls[control][2](sig[3])
|
||||||
@ -277,24 +294,21 @@ local function finalPrompt()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local gpu = gpuG()
|
helpActive, buttonsActive = false, false
|
||||||
rstfbDraw(gpu)
|
|
||||||
advDraw(gpu)
|
|
||||||
return safeModeActive
|
return safeModeActive
|
||||||
end
|
end
|
||||||
local function postPrompt()
|
local function postPrompt()
|
||||||
local gpu = gpuG()
|
|
||||||
local nsm = neo.requestAccess("x.neo.sys.manage")
|
local nsm = neo.requestAccess("x.neo.sys.manage")
|
||||||
local sh = "sys-everest"
|
local sh = "sys-everest"
|
||||||
warnings = {"Unable to get sys-init.shell due to no NSM, using sys-everest"}
|
console = {"Unable to get shell (no sys-glacier)"}
|
||||||
if nsm then
|
if nsm then
|
||||||
sh = nsm.getSetting("sys-init.shell") or sh
|
sh = nsm.getSetting("sys-init.shell") or sh
|
||||||
warnings = {"Starting " .. sh}
|
console = {"Starting " .. sh}
|
||||||
end
|
end
|
||||||
rstfbDraw(gpu)
|
basicDraw()
|
||||||
advDraw(gpu)
|
|
||||||
performDisclaim()
|
performDisclaim()
|
||||||
neo.executeAsync(sh)
|
neo.executeAsync(sh)
|
||||||
|
-- There's a delay here to allow taking the monitor.
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
for i = 1, 9 do
|
for i = 1, 9 do
|
||||||
local v = neo.requestAccess("x.neo.sys.session")
|
local v = neo.requestAccess("x.neo.sys.session")
|
||||||
@ -304,16 +318,16 @@ local function postPrompt()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- ...oh. hope this works then?
|
-- ...oh. hope this works then?
|
||||||
warnings = {"That wasn't a shell. Try Safe Mode."}
|
console = {"x.neo.sys.session not found, try Safe Mode."}
|
||||||
rstfbDraw(gpu)
|
retrieveNssMonitor(screen)
|
||||||
advDraw(gpu)
|
basicDraw()
|
||||||
sleep(1)
|
sleep(1)
|
||||||
shutdown(true)
|
shutdown(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function initializeSystem()
|
local function initializeSystem()
|
||||||
-- System has just booted, bristol is in charge
|
-- System has just booted, bristol is in charge
|
||||||
-- Firstly, since we don't know scrcfg, let's work out something sensible.
|
-- No screen configuration, so just guess.
|
||||||
-- Note that we should try to keep going with this if there's no reason to do otherwise.
|
-- Note that we should try to keep going with this if there's no reason to do otherwise.
|
||||||
local gpuAc = neo.requestAccess("c.gpu")
|
local gpuAc = neo.requestAccess("c.gpu")
|
||||||
local screenAc = neo.requestAccess("c.screen")
|
local screenAc = neo.requestAccess("c.screen")
|
||||||
@ -340,55 +354,36 @@ local function initializeSystem()
|
|||||||
gW, gH = math.min(80, gW), math.min(25, gH)
|
gW, gH = math.min(80, gW), math.min(25, gH)
|
||||||
pcall(gpu.setResolution, gW, gH)
|
pcall(gpu.setResolution, gW, gH)
|
||||||
pcall(gpu.setDepth, gpu.maxDepth()) -- can crash on OCEmu if done at the "wrong time"
|
pcall(gpu.setDepth, gpu.maxDepth()) -- can crash on OCEmu if done at the "wrong time"
|
||||||
pcall(gpu.setForeground, 0x000000)
|
|
||||||
end
|
end
|
||||||
|
-- Setup the new GPU provider
|
||||||
|
gpuG = function () return gpu end
|
||||||
|
--
|
||||||
local w = 1
|
local w = 1
|
||||||
local steps = {
|
local steps = {"sys-glacier"}
|
||||||
"sys-glacier", -- (Glacier : Config, Screen, Power)
|
for i = 1, 4 do table.insert(steps, "WAIT") end
|
||||||
-- Let that start, and system GC
|
table.insert(steps, "INJECT")
|
||||||
"WAIT",
|
for i = 1, 8 do table.insert(steps, "WAIT") end
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
-- Start services
|
|
||||||
"INJECT",
|
|
||||||
-- extra GC time
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT",
|
|
||||||
"WAIT"
|
|
||||||
}
|
|
||||||
local stepCount = #steps
|
local stepCount = #steps
|
||||||
|
|
||||||
neo.scheduleTimer(os.uptime())
|
neo.scheduleTimer(os.uptime())
|
||||||
while true do
|
while true do
|
||||||
local ev = {coroutine.yield()}
|
local ev = {coroutine.yield()}
|
||||||
if ev[1] == "k.procnew" then
|
consoleEventHandler(ev)
|
||||||
table.insert(warnings, ev[2] .. "/" .. ev[3] .. " UP")
|
|
||||||
end
|
|
||||||
if ev[1] == "k.procdie" then
|
|
||||||
table.insert(warnings, ev[2] .. "/" .. ev[3] .. " DOWN")
|
|
||||||
table.insert(warnings, tostring(ev[4]))
|
|
||||||
end
|
|
||||||
if ev[1] == "k.timer" then
|
if ev[1] == "k.timer" then
|
||||||
if gpu then
|
if gpu then
|
||||||
pcall(gpu.setForeground, 0x000000)
|
local bg = 0xFFFFFF
|
||||||
if w < stepCount then
|
if w < stepCount then
|
||||||
local n = math.floor((w / stepCount) * 255)
|
local n = math.floor((w / stepCount) * 255)
|
||||||
pcall(gpu.setBackground, (n * 0x10000) + (n * 0x100) + n)
|
bg = (n * 0x10000) + (n * 0x100) + n
|
||||||
else
|
|
||||||
pcall(gpu.setBackground, 0xFFFFFF)
|
|
||||||
end
|
end
|
||||||
basicDraw(gpu)
|
basicDraw(bg)
|
||||||
end
|
end
|
||||||
if steps[w] then
|
if steps[w] then
|
||||||
if steps[w] == "INJECT" then
|
if steps[w] == "INJECT" then
|
||||||
local nsm = neo.requestAccess("x.neo.sys.manage")
|
local nsm = neo.requestAccess("x.neo.sys.manage")
|
||||||
if not nsm then
|
if not nsm then
|
||||||
table.insert(warnings, "Settings not available for INJECT.")
|
table.insert(console, "Settings not available for INJECT.")
|
||||||
else
|
else
|
||||||
local nextstepsA = {}
|
local nextstepsA = {}
|
||||||
local nextstepsB = {}
|
local nextstepsB = {}
|
||||||
@ -412,10 +407,8 @@ local function initializeSystem()
|
|||||||
else
|
else
|
||||||
local v, err = neo.executeAsync(steps[w])
|
local v, err = neo.executeAsync(steps[w])
|
||||||
if not v then
|
if not v then
|
||||||
neo.emergency(steps[w] .. " STF")
|
neo.emergency("failed start:", steps[w])
|
||||||
neo.emergency(err)
|
neo.emergency(err)
|
||||||
table.insert(warnings, steps[w] .. " STF")
|
|
||||||
table.insert(warnings, err)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -437,12 +430,10 @@ end
|
|||||||
-- System initialized
|
-- System initialized
|
||||||
if finalPrompt() then
|
if finalPrompt() then
|
||||||
-- Safe Mode
|
-- Safe Mode
|
||||||
local gpu = gpuG()
|
|
||||||
rstfbDraw(gpu)
|
|
||||||
basicDraw(gpu)
|
|
||||||
local nsm = neo.requestAccess("x.neo.sys.manage")
|
local nsm = neo.requestAccess("x.neo.sys.manage")
|
||||||
if nsm then
|
if nsm then
|
||||||
pcall(gpu.set, 2, 4, "Rebooting for Safe Mode...")
|
console = {"Rebooting for Safe Mode..."}
|
||||||
|
basicDraw()
|
||||||
for _, v in ipairs(nsm.listSettings()) do
|
for _, v in ipairs(nsm.listSettings()) do
|
||||||
if v ~= "password" then
|
if v ~= "password" then
|
||||||
nsm.delSetting(v)
|
nsm.delSetting(v)
|
||||||
@ -450,12 +441,14 @@ if finalPrompt() then
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- assume sysconf.lua did something very bad
|
-- assume sysconf.lua did something very bad
|
||||||
pcall(gpu.set, 2, 4, "No NSM. Wiping configuration completely.")
|
console = {"No NSM. Wiping configuration completely."}
|
||||||
local fs = neo.requestAccess("c.filesystem")
|
local fs = neo.requestAccess("c.filesystem")
|
||||||
if not fs then
|
if not fs then
|
||||||
pcall(gpu.set, 2, 4, "Failed to get permission, you're doomed.")
|
table.insert(console, "Failed to get permission, you're doomed.")
|
||||||
|
else
|
||||||
|
fs.primary.remove("/data/sys-glacier/sysconf.lua")
|
||||||
end
|
end
|
||||||
fs.primary.remove("/data/sys-glacier/sysconf.lua")
|
basicDraw()
|
||||||
end
|
end
|
||||||
-- Do not give anything a chance to alter the new configuration
|
-- Do not give anything a chance to alter the new configuration
|
||||||
shutdownEmergency(true)
|
shutdownEmergency(true)
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
@ -1,6 +1,10 @@
|
|||||||
-- KittenOS N.E.O Kernel: "Tell Mettaton I said hi."
|
-- KittenOS N.E.O Kernel: "Tell Mettaton I said hi."
|
||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- NOTE: local is considered unnecessary in kernel since 21 March
|
-- NOTE: local is considered unnecessary in kernel since 21 March
|
||||||
|
|
||||||
@ -459,7 +463,7 @@ function retrieveAccess(perm, pkg, pid)
|
|||||||
accesses[uid] = function (pkg, pid)
|
accesses[uid] = function (pkg, pid)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
return function (f)
|
return function (f, secret)
|
||||||
-- Registration function
|
-- Registration function
|
||||||
ensureType(f, "function")
|
ensureType(f, "function")
|
||||||
local accessObjectCache = {}
|
local accessObjectCache = {}
|
||||||
@ -481,8 +485,10 @@ function retrieveAccess(perm, pkg, pid)
|
|||||||
end
|
end
|
||||||
-- returns nil and fails
|
-- returns nil and fails
|
||||||
end
|
end
|
||||||
-- Announce registration
|
if not secret then
|
||||||
distEvent(nil, "k.registration", uid)
|
-- Announce registration
|
||||||
|
distEvent(nil, "k.registration", uid)
|
||||||
|
end
|
||||||
end, function ()
|
end, function ()
|
||||||
-- Registration becomes null (access is held but other processes cannot retrieve object)
|
-- Registration becomes null (access is held but other processes cannot retrieve object)
|
||||||
if accesses[uid] then
|
if accesses[uid] then
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- app-claw-core: assistant to app-claw
|
|
||||||
-- should only ever be one app-claw at a time
|
|
||||||
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
|
|
||||||
-- SO DON'T DO IT.
|
|
||||||
|
|
||||||
-- Also serves to provide a mutex.
|
|
||||||
|
|
||||||
local lock = false
|
|
||||||
|
|
||||||
return function ()
|
|
||||||
if lock then
|
|
||||||
error("libclaw safety lock in use")
|
|
||||||
end
|
|
||||||
lock = true
|
|
||||||
local sourceList = {}
|
|
||||||
local sources = {}
|
|
||||||
-- 1 2 3 4 5 6
|
|
||||||
-- source ents: src dst index
|
|
||||||
-- dst entries: writeFile(fn), mkdir(fn), exists(fn), isDirectory(fn), remove(fn), rename(fna, fnb)
|
|
||||||
-- writeFile(fn) -> function (data/nil to close)
|
|
||||||
local function saveInfo(dn)
|
|
||||||
sources[dn][2][2]("data")
|
|
||||||
sources[dn][2][2]("data/app-claw")
|
|
||||||
local cb, _, r = sources[dn][2][1]("data/app-claw/local.lua")
|
|
||||||
if not cb then return false, r end
|
|
||||||
_, r = cb(require("serial").serialize(sources[dn][3]))
|
|
||||||
if not _ then return false, r end
|
|
||||||
_, r = cb(nil)
|
|
||||||
if not _ then return false, r end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
local remove, installTo, expandCSI, compressCSI
|
|
||||||
local function expandS(v)
|
|
||||||
return v:sub(2, v:byte(1) + 1), v:sub(v:byte(1) + 2)
|
|
||||||
end
|
|
||||||
local function expandT(v)
|
|
||||||
local t = {}
|
|
||||||
local n = v:byte(1)
|
|
||||||
v = v:sub(2)
|
|
||||||
for i = 1, n do
|
|
||||||
t[i], v = expandS(v)
|
|
||||||
end
|
|
||||||
return t, v
|
|
||||||
end
|
|
||||||
local function compressT(x)
|
|
||||||
local b = string.char(#x)
|
|
||||||
for _, v in ipairs(x) do
|
|
||||||
b = b .. string.char(#v) .. v
|
|
||||||
end
|
|
||||||
return b
|
|
||||||
end
|
|
||||||
local function expandCSI(v)
|
|
||||||
local t = {}
|
|
||||||
local k
|
|
||||||
k, v = expandS(v)
|
|
||||||
t.desc, v = expandS(v)
|
|
||||||
t.v = (v:byte(1) * 256) + v:byte(2)
|
|
||||||
v = v:sub(3)
|
|
||||||
t.dirs, v = expandT(v)
|
|
||||||
t.files, v = expandT(v)
|
|
||||||
t.deps, v = expandT(v)
|
|
||||||
return k, t, v
|
|
||||||
end
|
|
||||||
local function compressCSI(k, v)
|
|
||||||
local nifo = string.char(#k) .. k
|
|
||||||
nifo = nifo .. string.char(math.min(255, #v.desc)) .. v.desc:sub(1, 255)
|
|
||||||
nifo = nifo .. string.char(math.floor(v.v / 256), v.v % 256)
|
|
||||||
nifo = nifo .. compressT(v.dirs)
|
|
||||||
nifo = nifo .. compressT(v.files)
|
|
||||||
nifo = nifo .. compressT(v.deps)
|
|
||||||
return nifo
|
|
||||||
end
|
|
||||||
local function findPkg(idx, pkg, del)
|
|
||||||
del = del and ""
|
|
||||||
idx = sources[idx][3]
|
|
||||||
while #idx > 0 do
|
|
||||||
local k, d
|
|
||||||
k, d, idx = expandCSI(idx)
|
|
||||||
if del then
|
|
||||||
if k == pkg then
|
|
||||||
return d, del .. idx
|
|
||||||
end
|
|
||||||
del = del .. compressCSI(k, d)
|
|
||||||
else
|
|
||||||
if k == pkg then return d end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- NOTE: Functions in this must return something due to the checked-call wrapper,
|
|
||||||
-- but should all use error() for consistency.
|
|
||||||
-- Operations
|
|
||||||
installTo = function (dstName, pkg, srcName, checked, yielder)
|
|
||||||
local errs = {}
|
|
||||||
if srcName == dstName then
|
|
||||||
error("Invalid API use")
|
|
||||||
end
|
|
||||||
-- preliminary checks
|
|
||||||
local srcPkg = findPkg(srcName, pkg, false)
|
|
||||||
assert(srcPkg)
|
|
||||||
if checked then
|
|
||||||
for _, v in ipairs(srcPkg.deps) do
|
|
||||||
if not findPkg(dstName, v) then
|
|
||||||
if not findPkg(srcName, v) then
|
|
||||||
table.insert(errs, pkg .. " depends on " .. v .. "\n")
|
|
||||||
elseif #errs == 0 then
|
|
||||||
installTo(dstName, v, srcName, checked, yielder)
|
|
||||||
else
|
|
||||||
table.insert(errs, pkg .. " depends on " .. v .. " (can autoinstall)\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Files from previous versions to get rid of
|
|
||||||
local ignFiles = {}
|
|
||||||
local oldDst = findPkg(dstName, pkg)
|
|
||||||
if oldDst then
|
|
||||||
for _, v in ipairs(oldDst.files) do
|
|
||||||
ignFiles[v] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
oldDst = nil
|
|
||||||
for _, v in ipairs(srcPkg.files) do
|
|
||||||
if not ignFiles[v] then
|
|
||||||
if sources[dstName][2][3](v) then
|
|
||||||
table.insert(errs, v .. " already exists (corrupt system?)")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #errs > 0 then
|
|
||||||
error(table.concat(errs))
|
|
||||||
end
|
|
||||||
for _, v in ipairs(srcPkg.dirs) do
|
|
||||||
sources[dstName][2][2](v)
|
|
||||||
if not sources[dstName][2][4](v) then
|
|
||||||
error("Unable to create directory " .. v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, v in ipairs(srcPkg.files) do
|
|
||||||
local tmpOut, r, ok = sources[dstName][2][1](v .. ".claw-tmp")
|
|
||||||
ok = tmpOut
|
|
||||||
if ok then
|
|
||||||
ok, r = sources[srcName][1](v, tmpOut)
|
|
||||||
end
|
|
||||||
if ok then
|
|
||||||
yielder()
|
|
||||||
else
|
|
||||||
-- Cleanup...
|
|
||||||
for _, v in ipairs(srcPkg.files) do
|
|
||||||
sources[dstName][2][5](v .. ".claw-tmp")
|
|
||||||
end
|
|
||||||
error(r)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- PAST THIS POINT, ERRORS CORRUPT!
|
|
||||||
-- Remove package from DB
|
|
||||||
local oldDst2, oldDst3 = findPkg(dstName, pkg, true)
|
|
||||||
sources[dstName][3] = oldDst3 or sources[dstName][3]
|
|
||||||
oldDst2, oldDst3 = nil
|
|
||||||
saveInfo(dstName)
|
|
||||||
-- Delete old files
|
|
||||||
for k, _ in pairs(ignFiles) do
|
|
||||||
yielder()
|
|
||||||
sources[dstName][2][5](k)
|
|
||||||
end
|
|
||||||
-- Create new files
|
|
||||||
for _, v in ipairs(srcPkg.files) do
|
|
||||||
yielder()
|
|
||||||
sources[dstName][2][6](v .. ".claw-tmp", v)
|
|
||||||
end
|
|
||||||
-- Insert into DB
|
|
||||||
sources[dstName][3] = sources[dstName][3] .. compressCSI(pkg, srcPkg)
|
|
||||||
saveInfo(dstName)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
remove = function (dstName, pkg, checked)
|
|
||||||
if checked then
|
|
||||||
local errs = {}
|
|
||||||
local buf = sources[dstName][3]
|
|
||||||
while #buf > 0 do
|
|
||||||
local dpsName, dpsV
|
|
||||||
dpsName, dpsV, buf = expandCSI(buf)
|
|
||||||
for _, v in ipairs(dpsV.deps) do
|
|
||||||
if v == pkg then
|
|
||||||
table.insert(errs, dpsName .. " depends on " .. pkg .. "\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #errs > 0 then
|
|
||||||
return nil, table.concat(errs)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local dstPkg, nbuf = findPkg(dstName, pkg, true)
|
|
||||||
assert(dstPkg, "Package wasn't installed")
|
|
||||||
for _, v in ipairs(dstPkg.files) do
|
|
||||||
sources[dstName][2][5](v)
|
|
||||||
end
|
|
||||||
sources[dstName][3] = nbuf
|
|
||||||
saveInfo(dstName)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return {
|
|
||||||
-- Gets the latest info, or if given a source just gives that source's info.
|
|
||||||
-- Do not modify output.
|
|
||||||
getInfo = function (pkg, source, oldest)
|
|
||||||
if source then return findPkg(source, pkg) end
|
|
||||||
local bestI = {
|
|
||||||
v = -1,
|
|
||||||
desc = "An unknown package.",
|
|
||||||
deps = {}
|
|
||||||
}
|
|
||||||
if oldest then bestI.v = 10000 end
|
|
||||||
for k, v in pairs(sources) do
|
|
||||||
local pkgv = findPkg(k, pkg)
|
|
||||||
if pkgv then
|
|
||||||
if ((not oldest) and (pkgv.v > bestI.v)) or (oldest and (pkgv.v > bestI.v)) then
|
|
||||||
bestI = pkgv
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return bestI
|
|
||||||
end,
|
|
||||||
sources = sources,
|
|
||||||
sourceList = sourceList,
|
|
||||||
remove = remove,
|
|
||||||
installTo = installTo,
|
|
||||||
expandCSI = expandCSI,
|
|
||||||
compressCSI = compressCSI,
|
|
||||||
|
|
||||||
-- Gets a total list of packages, as a table of strings. You can modify output.
|
|
||||||
getList = function ()
|
|
||||||
local n = {}
|
|
||||||
local seen = {}
|
|
||||||
for k, v in pairs(sources) do
|
|
||||||
local p3 = v[3]
|
|
||||||
while #p3 > 0 do
|
|
||||||
local kb, _, nx = expandCSI(p3)
|
|
||||||
p3 = nx
|
|
||||||
if not seen[kb] then
|
|
||||||
seen[kb] = true
|
|
||||||
table.insert(n, kb)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(n)
|
|
||||||
return n
|
|
||||||
end,
|
|
||||||
unlock = function ()
|
|
||||||
lock = false
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
@ -1,28 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- app-claw-csi: addSource function
|
|
||||||
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
|
|
||||||
-- SO DON'T DO IT.
|
|
||||||
|
|
||||||
-- NOTE: If a source is writable, it's added anyway despite any problems.
|
|
||||||
return function (claw, name, src, dst)
|
|
||||||
local ifo = ""
|
|
||||||
local ifok, e = src("data/app-claw/local.lua", function (t)
|
|
||||||
ifo = ifo .. (t or "")
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
e = e or "local.lua parse error"
|
|
||||||
ifo = ifok and require("serial").deserialize(ifo)
|
|
||||||
if not (dst or ifo) then return false, e end
|
|
||||||
table.insert(claw.sourceList, {name, not not dst})
|
|
||||||
local nifo = ifo or ""
|
|
||||||
if type(nifo) == "table" then
|
|
||||||
nifo = ""
|
|
||||||
for k, v in pairs(ifo) do
|
|
||||||
nifo = nifo .. claw.compressCSI(k, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
claw.sources[name] = {src, dst, nifo}
|
|
||||||
return not not ifo, e
|
|
||||||
end
|
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- bmp: Portable OC BMP/DIB library
|
-- bmp: Portable OC BMP/DIB library
|
||||||
-- Flexible: Reading can be set to
|
-- Flexible: Reading can be set to
|
||||||
@ -153,20 +157,8 @@ return {
|
|||||||
local planes = get16(0x1A)
|
local planes = get16(0x1A)
|
||||||
local bpp = get16(0x1C)
|
local bpp = get16(0x1C)
|
||||||
local compression = get32(0x1E)
|
local compression = get32(0x1E)
|
||||||
local paletteCol = 0
|
local paletteCol = get32(0x2E)
|
||||||
local other = get32(0x2E)
|
|
||||||
paletteCol = other
|
|
||||||
-- postprocess
|
|
||||||
|
|
||||||
-- The actual values used for addressing, for cMode to mess with
|
|
||||||
local basePtr = 14 + hdrSize + (paletteCol * 4)
|
|
||||||
local scanWB = math.ceil((bpp * width) / 32) * 4
|
|
||||||
local monoWB = (math.ceil((bpp * width) / 32) * 4)
|
|
||||||
local planeWB = scanWB * height
|
|
||||||
|
|
||||||
if not packed then
|
|
||||||
basePtr = get32(0x0A) -- 'BM' header
|
|
||||||
end
|
|
||||||
-- negative height means sane coords
|
-- negative height means sane coords
|
||||||
local upDown = true
|
local upDown = true
|
||||||
if height >= 0x80000000 then
|
if height >= 0x80000000 then
|
||||||
@ -175,6 +167,18 @@ return {
|
|||||||
upDown = false
|
upDown = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- postprocess
|
||||||
|
|
||||||
|
-- The actual values used for addressing, for cMode to mess with
|
||||||
|
local basePtr = 14 + hdrSize + (paletteCol * 4)
|
||||||
|
local scanWB = math.ceil((bpp * width) / 32) * 4
|
||||||
|
local monoWB = math.ceil(width / 32) * 4
|
||||||
|
local planeWB = scanWB * height
|
||||||
|
|
||||||
|
if not packed then
|
||||||
|
basePtr = get32(0x0A) -- 'BM' header
|
||||||
|
end
|
||||||
|
|
||||||
-- Cursor/Icon
|
-- Cursor/Icon
|
||||||
if cMode then
|
if cMode then
|
||||||
height = math.floor(height / 2)
|
height = math.floor(height / 2)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- Braille Converter & NeoUX component
|
-- Braille Converter & NeoUX component
|
||||||
-- While the Neoux part isn't OS-independent,
|
-- While the Neoux part isn't OS-independent,
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- event: Implements pull/listen semantics in a consistent way for a given process.
|
-- event: Implements pull/listen semantics in a consistent way for a given process.
|
||||||
-- This is similar in API to OpenOS's event framework, but is per-process.
|
-- This is similar in API to OpenOS's event framework, but is per-process.
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local fmt
|
local fmt
|
||||||
fmt = {
|
fmt = {
|
||||||
|
77
code/libs/lineedit.lua
Normal file
77
code/libs/lineedit.lua
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
return {
|
||||||
|
-- note: everything must already be unicode.safeTextFormat'd
|
||||||
|
draw = function (sW, line, cursorX, rX)
|
||||||
|
-- if no camera, provide a default
|
||||||
|
rX = rX or math.max(1, (cursorX or 1) - math.floor(sW * 2 / 3))
|
||||||
|
-- transform into area-relative
|
||||||
|
local tl = unicode.sub(line, rX, rX + sW - 1)
|
||||||
|
-- inject cursor
|
||||||
|
if cursorX then
|
||||||
|
cursorX = (cursorX - rX) + 1
|
||||||
|
if cursorX >= 1 then
|
||||||
|
if cursorX <= sW then
|
||||||
|
tl = unicode.sub(tl, 1, cursorX - 1) .. "_" .. unicode.sub(tl, cursorX + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return tl .. (" "):rep(sW - unicode.len(tl))
|
||||||
|
end,
|
||||||
|
clamp = function (tl, cursorX)
|
||||||
|
tl = unicode.len(tl)
|
||||||
|
if tl < cursorX - 1 then
|
||||||
|
return tl + 1
|
||||||
|
end
|
||||||
|
return cursorX
|
||||||
|
end,
|
||||||
|
-- returns line, cursorX, special
|
||||||
|
-- return values may be nil if irrelevant
|
||||||
|
key = function (ks, kc, line, cursorX)
|
||||||
|
local cS = unicode.sub(line, 1, cursorX - 1)
|
||||||
|
local cE = unicode.sub(line, cursorX)
|
||||||
|
local ll = unicode.len(line)
|
||||||
|
if kc == 203 then -- navi <
|
||||||
|
if cursorX > 1 then
|
||||||
|
return nil, cursorX - 1
|
||||||
|
else
|
||||||
|
-- cline underflow
|
||||||
|
return nil, nil, "l<"
|
||||||
|
end
|
||||||
|
elseif kc == 205 then -- navi >
|
||||||
|
if cursorX > ll then
|
||||||
|
-- cline overflow
|
||||||
|
return nil, nil, "l>"
|
||||||
|
end
|
||||||
|
return nil, cursorX + 1
|
||||||
|
elseif kc == 199 then -- home
|
||||||
|
return nil, 1
|
||||||
|
elseif kc == 207 then -- end
|
||||||
|
return nil, unicode.len(line) + 1
|
||||||
|
elseif ks == "\8" then -- del
|
||||||
|
if cursorX == 1 then
|
||||||
|
-- weld prev
|
||||||
|
return nil, nil, "w<"
|
||||||
|
else
|
||||||
|
return unicode.sub(cS, 1, unicode.len(cS) - 1) .. cE, cursorX - 1
|
||||||
|
end
|
||||||
|
elseif kc == 211 then -- del
|
||||||
|
if cursorX > ll then
|
||||||
|
return nil, nil, "w>"
|
||||||
|
end
|
||||||
|
return cS .. unicode.sub(cE, 2)
|
||||||
|
elseif ks then -- standard letters
|
||||||
|
if ks == "\r" then
|
||||||
|
-- new line
|
||||||
|
return nil, nil, "nl"
|
||||||
|
end
|
||||||
|
return cS .. ks .. cE, cursorX + unicode.len(ks)
|
||||||
|
end
|
||||||
|
-- :(
|
||||||
|
end
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- neoux: Implements utilities on top of Everest & event:
|
-- neoux: Implements utilities on top of Everest & event:
|
||||||
-- Everest crash protection
|
-- Everest crash protection
|
||||||
@ -25,7 +29,7 @@ newNeoux = function (event, neo)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
local neoux = {}
|
local neoux = {}
|
||||||
neoux.fileDialog = function (forWrite, callback)
|
neoux.fileDialog = function (forWrite, callback, dfn)
|
||||||
local sync = false
|
local sync = false
|
||||||
local rtt = nil
|
local rtt = nil
|
||||||
if not callback then
|
if not callback then
|
||||||
@ -35,7 +39,7 @@ newNeoux = function (event, neo)
|
|||||||
rtt = rt
|
rtt = rt
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local tag = neo.requireAccess("x.neo.pub.base", "filedialog").showFileDialogAsync(forWrite)
|
local tag = neo.requireAccess("x.neo.pub.base", "filedialog").showFileDialogAsync(forWrite, dfn)
|
||||||
local f
|
local f
|
||||||
f = function (_, fd, tg, re)
|
f = function (_, fd, tg, re)
|
||||||
if fd == "filedialog" then
|
if fd == "filedialog" then
|
||||||
@ -339,6 +343,8 @@ newNeoux = function (event, neo)
|
|||||||
end
|
end
|
||||||
-- Note: w should be at least 2 - this is similar to buttons.
|
-- Note: w should be at least 2 - this is similar to buttons.
|
||||||
neoux.tcfield = function (x, y, w, textprop)
|
neoux.tcfield = function (x, y, w, textprop)
|
||||||
|
-- compat. workaround for apps which nuke tcfields
|
||||||
|
local p = unicode.len(textprop()) + 1
|
||||||
return {
|
return {
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
@ -347,22 +353,24 @@ newNeoux = function (event, neo)
|
|||||||
selectable = true,
|
selectable = true,
|
||||||
key = function (window, update, a, c, d, f)
|
key = function (window, update, a, c, d, f)
|
||||||
if d then
|
if d then
|
||||||
|
local ot = textprop()
|
||||||
|
local le = require("lineedit")
|
||||||
|
p = le.clamp(ot, p)
|
||||||
if c == 63 then
|
if c == 63 then
|
||||||
neo.requireAccess("x.neo.pub.globals", "clipboard").setSetting("clipboard", textprop())
|
neo.requireAccess("x.neo.pub.globals", "clipboard").setSetting("clipboard", ot)
|
||||||
elseif c == 64 then
|
elseif c == 64 then
|
||||||
local contents = neo.requireAccess("x.neo.pub.globals", "clipboard").getSetting("clipboard")
|
local contents = neo.requireAccess("x.neo.pub.globals", "clipboard").getSetting("clipboard")
|
||||||
contents = contents:match("^[^\r\n]*")
|
contents = contents:match("^[^\r\n]*")
|
||||||
textprop(contents)
|
textprop(contents)
|
||||||
update()
|
update()
|
||||||
elseif a == 8 then
|
elseif a ~= 9 then
|
||||||
local str = textprop()
|
local lT, lC, lX = le.key(a ~= 0 and unicode.char(a), c, ot, p)
|
||||||
textprop(unicode.sub(str, 1, unicode.len(str) - 1))
|
if lT or lC then
|
||||||
update()
|
if lT then textprop(lT) end
|
||||||
return true
|
p = lC or p
|
||||||
elseif a >= 32 then
|
update()
|
||||||
textprop(textprop() .. unicode.char(a))
|
return true
|
||||||
update()
|
end
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -377,9 +385,10 @@ newNeoux = function (event, neo)
|
|||||||
fg = bg
|
fg = bg
|
||||||
bg = fg1
|
bg = fg1
|
||||||
end
|
end
|
||||||
local text = unicode.safeTextFormat(textprop())
|
local t, e, r = textprop(), require("lineedit")
|
||||||
text = "[" .. neoux.pad(text, w - 2, false, true, true) .. "]"
|
p = e.clamp(t, p)
|
||||||
window.span(x, y, text, bg, fg)
|
t, r = unicode.safeTextFormat(t, p)
|
||||||
|
window.span(x, y, "[" .. e.draw(w - 2, t, selected and r) .. "]", bg, fg)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local doSerialize = nil
|
local doSerialize = nil
|
||||||
function doSerialize(s)
|
function doSerialize(s)
|
||||||
if type(s) == "table" then
|
if type(s) == "table" then
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- just don't bother with proper indent here
|
-- just don't bother with proper indent here
|
||||||
return function (event, nexus, retFunc, fs, pkg, mode)
|
return function (event, nexus, retFunc, fs, pkg, mode, defName)
|
||||||
|
|
||||||
local fmt = require("fmttext")
|
local fmt = require("fmttext")
|
||||||
local class = "manage"
|
local class = "manage"
|
||||||
@ -141,7 +145,7 @@ end
|
|||||||
nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c)
|
nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c)
|
||||||
if not wnd then
|
if not wnd then
|
||||||
wnd = w
|
wnd = w
|
||||||
prepareNode(require("sys-filevfs")(fs, mode))
|
prepareNode(require("sys-filevfs")(fs, mode, defName))
|
||||||
end
|
end
|
||||||
if ev == "key" then
|
if ev == "key" then
|
||||||
key2(a, b, c)
|
key2(a, b, c)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- Used by filedialog to provide a sane relative environment.
|
-- Used by filedialog to provide a sane relative environment.
|
||||||
-- Essentially, the filedialog is just a 'thin' UI wrapper over this.
|
-- Essentially, the filedialog is just a 'thin' UI wrapper over this.
|
||||||
@ -16,12 +20,12 @@ end
|
|||||||
|
|
||||||
local getFsNode, getRoot
|
local getFsNode, getRoot
|
||||||
local setupCopyNode
|
local setupCopyNode
|
||||||
function setupCopyNode(parent, myRoot, op, complete, impliedName)
|
function setupCopyNode(parent, myRoot, op, complete)
|
||||||
local function handleResult(aRes, res)
|
local function handleResult(aRes, res)
|
||||||
if aRes then
|
if aRes then
|
||||||
return complete(res, true)
|
return complete(res, true)
|
||||||
else
|
else
|
||||||
return nil, setupCopyNode(parent, res, op, complete, impliedName)
|
return nil, setupCopyNode(parent, res, op, complete)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return {
|
return {
|
||||||
@ -32,11 +36,6 @@ function setupCopyNode(parent, myRoot, op, complete, impliedName)
|
|||||||
complete(nil, false)
|
complete(nil, false)
|
||||||
return false, parent
|
return false, parent
|
||||||
end})
|
end})
|
||||||
if impliedName and myRoot.unknownAvailable then
|
|
||||||
table.insert(l, {"Implied: " .. impliedName, function ()
|
|
||||||
return handleResult(myRoot.selectUnknown(impliedName))
|
|
||||||
end})
|
|
||||||
end
|
|
||||||
for _, v in ipairs(myRoot.list()) do
|
for _, v in ipairs(myRoot.list()) do
|
||||||
table.insert(l, {v[1], function ()
|
table.insert(l, {v[1], function ()
|
||||||
return handleResult(v[2]())
|
return handleResult(v[2]())
|
||||||
@ -54,7 +53,7 @@ local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
|
|||||||
if not fwrap then
|
if not fwrap then
|
||||||
return false, dialog("Could not open source", parent)
|
return false, dialog("Could not open source", parent)
|
||||||
end
|
end
|
||||||
local myRoot = getRoot(fs, true)
|
local myRoot = getRoot(fs, true, impliedName)
|
||||||
-- Setup wrapping node
|
-- Setup wrapping node
|
||||||
return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent)
|
return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent)
|
||||||
if not fwrap2 then
|
if not fwrap2 then
|
||||||
@ -72,14 +71,22 @@ local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
|
|||||||
fwrap.close()
|
fwrap.close()
|
||||||
fwrap2.close()
|
fwrap2.close()
|
||||||
return false, dialog("Completed copy.", parent)
|
return false, dialog("Completed copy.", parent)
|
||||||
end, impliedName)
|
end)
|
||||||
end
|
end
|
||||||
function getFsNode(fs, parent, fsc, path, mode)
|
function getFsNode(fs, parent, fsc, path, mode, impliedName)
|
||||||
local va = fsc.address:sub(1, 4)
|
local va = fsc.address:sub(1, 4)
|
||||||
local fscrw = not fsc.isReadOnly()
|
local fscrw = not fsc.isReadOnly()
|
||||||
local dir = path:sub(#path, #path) == "/"
|
local dir = path:sub(#path, #path) == "/"
|
||||||
local confirmedDel = false
|
local confirmedDel = false
|
||||||
local t
|
local t
|
||||||
|
local function selectUnknown(text)
|
||||||
|
-- Relies on text being nil if used in leaf node
|
||||||
|
local rt, re = require("sys-filewrap").create(fsc, path .. (text or ""), mode)
|
||||||
|
if not rt then
|
||||||
|
return false, dialog("Open Error: " .. tostring(re), parent)
|
||||||
|
end
|
||||||
|
return true, rt
|
||||||
|
end
|
||||||
t = {
|
t = {
|
||||||
name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
|
name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
|
||||||
list = function ()
|
list = function ()
|
||||||
@ -91,11 +98,25 @@ function getFsNode(fs, parent, fsc, path, mode)
|
|||||||
for k, v in ipairs(fsc.list(path)) do
|
for k, v in ipairs(fsc.list(path)) do
|
||||||
local nm = "F: " .. v
|
local nm = "F: " .. v
|
||||||
local fp = path .. v
|
local fp = path .. v
|
||||||
if fsc.isDirectory(fp) then
|
local cDir = fsc.isDirectory(fp)
|
||||||
|
if cDir then
|
||||||
nm = "D: " .. v
|
nm = "D: " .. v
|
||||||
end
|
end
|
||||||
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end}
|
if (not cDir) and (fscrw or mode == false) and (mode ~= nil) then
|
||||||
|
local vn = v
|
||||||
|
n[k + 1] = {nm, function () return selectUnknown(vn) end}
|
||||||
|
else
|
||||||
|
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode, impliedName) end}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
table.insert(n, {"Copy", function ()
|
||||||
|
local rt, re = require("sys-filewrap").create(fsc, path, false)
|
||||||
|
if not rt then
|
||||||
|
return false, dialog("Open Error: " .. tostring(re), parent)
|
||||||
|
end
|
||||||
|
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
|
||||||
|
end})
|
||||||
end
|
end
|
||||||
if fscrw then
|
if fscrw then
|
||||||
if dir then
|
if dir then
|
||||||
@ -114,31 +135,6 @@ function getFsNode(fs, parent, fsc, path, mode)
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
end})
|
end})
|
||||||
else
|
|
||||||
if mode ~= nil then
|
|
||||||
local tx = "Open"
|
|
||||||
if mode == true then
|
|
||||||
tx = "Save"
|
|
||||||
elseif mode == "append" then
|
|
||||||
tx = "Append"
|
|
||||||
end
|
|
||||||
if fscrw or mode == false then
|
|
||||||
table.insert(n, {tx, function ()
|
|
||||||
local rt, re = require("sys-filewrap").create(fsc, path, mode)
|
|
||||||
if not rt then
|
|
||||||
return false, dialog("Open Error: " .. tostring(re), parent)
|
|
||||||
end
|
|
||||||
return true, rt
|
|
||||||
end})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.insert(n, {"Copy", function ()
|
|
||||||
local rt, re = require("sys-filewrap").create(fsc, path, false)
|
|
||||||
if not rt then
|
|
||||||
return false, dialog("Open Error: " .. tostring(re), parent)
|
|
||||||
end
|
|
||||||
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
|
|
||||||
end})
|
|
||||||
end
|
end
|
||||||
if path ~= "/" then
|
if path ~= "/" then
|
||||||
local delText = "Delete"
|
local delText = "Delete"
|
||||||
@ -172,20 +168,20 @@ function getFsNode(fs, parent, fsc, path, mode)
|
|||||||
end})
|
end})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if not dir then
|
||||||
|
elseif impliedName then
|
||||||
|
table.insert(n, {"Implied: " .. impliedName, function ()
|
||||||
|
return selectUnknown(impliedName)
|
||||||
|
end})
|
||||||
|
end
|
||||||
return n
|
return n
|
||||||
end,
|
end,
|
||||||
unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
|
unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
|
||||||
selectUnknown = function (text)
|
selectUnknown = selectUnknown
|
||||||
local rt, re = require("sys-filewrap").create(fsc, path .. text, mode)
|
|
||||||
if not rt then
|
|
||||||
return false, dialog("Open Error: " .. tostring(re), parent)
|
|
||||||
end
|
|
||||||
return true, rt
|
|
||||||
end
|
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
function getRoot(fs, mode)
|
function getRoot(fs, mode, defName)
|
||||||
local t
|
local t
|
||||||
t = {
|
t = {
|
||||||
name = "DRVS:",
|
name = "DRVS:",
|
||||||
@ -209,7 +205,7 @@ function getRoot(fs, mode)
|
|||||||
id = "RW " .. amount .. "% " .. mb .. "M " .. id
|
id = "RW " .. amount .. "% " .. mb .. "M " .. id
|
||||||
end
|
end
|
||||||
table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function ()
|
table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function ()
|
||||||
return nil, getFsNode(fs, t, fsi, "/", mode)
|
return nil, getFsNode(fs, t, fsi, "/", mode, defName)
|
||||||
end})
|
end})
|
||||||
end
|
end
|
||||||
return l
|
return l
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
local function ensureMode(mode)
|
local function ensureMode(mode)
|
||||||
local n = "rb"
|
local n = "rb"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
return function (
|
return function (
|
||||||
gpus, screens,
|
gpus, screens,
|
||||||
@ -95,7 +99,7 @@ return function (
|
|||||||
return v, didBind
|
return v, didBind
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end, v
|
end, monitor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-- This is released into the public domain.
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
-- No warranty is provided, implied or otherwise.
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- CRITICAL FILE!
|
-- CRITICAL FILE!
|
||||||
-- This file defines how your KittenOS NEO system responds to access requests.
|
-- This file defines how your KittenOS NEO system responds to access requests.
|
||||||
@ -11,21 +15,28 @@
|
|||||||
-- IRC is usually pretty safe, but no guarantees.
|
-- IRC is usually pretty safe, but no guarantees.
|
||||||
|
|
||||||
-- Returns "allow", "deny", or "ask".
|
-- Returns "allow", "deny", or "ask".
|
||||||
local function actualPolicy(pkg, pid, perm, matchesSvc)
|
local function actualPolicy(pkg, pid, perm, pkgSvcPfx)
|
||||||
-- System stuff is allowed.
|
-- System stuff is allowed.
|
||||||
if pkg:sub(1, 4) == "sys-" then
|
if pkg:sub(1, 4) == "sys-" then
|
||||||
return "allow"
|
return "allow"
|
||||||
end
|
end
|
||||||
|
-- svc-t's job is solely to emulate terminals
|
||||||
|
-- TO INSTALL YOUR OWN TERMINAL EMULATOR:
|
||||||
|
-- perm|app-yourterm|r.neo.t
|
||||||
|
if pkg == "svc-t" and perm == "r.neo.pub.t" then
|
||||||
|
return "allow"
|
||||||
|
end
|
||||||
-- <The following is for apps & services>
|
-- <The following is for apps & services>
|
||||||
-- x.neo.pub (aka Icecap) is open to all
|
-- x.neo.pub.* is open to all
|
||||||
if perm:sub(1, 10) == "x.neo.pub." then
|
if perm:sub(1, 10) == "x.neo.pub." then
|
||||||
return "allow"
|
return "allow"
|
||||||
end
|
end
|
||||||
-- These signals are harmless, though they identify HW (as does everything in OC...)
|
-- These signals are harmless, though they identify HW (as does everything in OC...)
|
||||||
if perm == "s.h.component_added" or perm == "s.h.component_removed" then
|
if perm == "s.h.component_added" or perm == "s.h.component_removed" or perm == "s.h.tablet_use" or perm == "c.tablet" then
|
||||||
return "allow"
|
return "allow"
|
||||||
end
|
end
|
||||||
if matchesSvc("r.", pkg, perm) then
|
-- Userlevel can register for itself
|
||||||
|
if perm == "r." .. pkgSvcPfx then
|
||||||
return "allow"
|
return "allow"
|
||||||
end
|
end
|
||||||
-- Userlevel has no other registration rights
|
-- Userlevel has no other registration rights
|
||||||
@ -44,8 +55,8 @@ local function actualPolicy(pkg, pid, perm, matchesSvc)
|
|||||||
return "ask"
|
return "ask"
|
||||||
end
|
end
|
||||||
|
|
||||||
return function (nexus, settings, pkg, pid, perm, rsp, matchesSvc)
|
return function (nexus, settings, pkg, pid, perm, rsp, pkgSvcPfx)
|
||||||
local res = actualPolicy(pkg, pid, perm, matchesSvc)
|
local res = actualPolicy(pkg, pid, perm, pkgSvcPfx)
|
||||||
if settings then
|
if settings then
|
||||||
res = settings.getSetting("perm|" .. pkg .. "|" .. perm) or
|
res = settings.getSetting("perm|" .. pkg .. "|" .. perm) or
|
||||||
settings.getSetting("perm|*|" .. perm) or res
|
settings.getSetting("perm|*|" .. perm) or res
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- BDIVIDE
|
|
||||||
-- format:
|
|
||||||
-- 0-127 for constants
|
|
||||||
-- <block + 128>, <(len - 3) * 2, + lowest bit is upper bit of position>, <position - 1>
|
|
||||||
|
|
||||||
io.write("\x00") -- initiation character
|
|
||||||
|
|
||||||
local blockCache = {}
|
|
||||||
local window = 0
|
|
||||||
local blockUse = 128
|
|
||||||
for i = 128, 128 + blockUse - 1 do
|
|
||||||
blockCache[i] = ("\x00"):rep(512)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function runBlock(blk)
|
|
||||||
-- firstly, get current block index
|
|
||||||
local blockIndex = window + 128
|
|
||||||
window = (window + 1) % blockUse
|
|
||||||
blockCache[blockIndex] = ""
|
|
||||||
-- ok, now work on the problem
|
|
||||||
local i = 1
|
|
||||||
while i <= #blk do
|
|
||||||
local bestData = blk:sub(i, i)
|
|
||||||
local bestRes = bestData
|
|
||||||
local bestScore = 1
|
|
||||||
for bid = 128, 128 + blockUse - 1 do
|
|
||||||
for lm = 0, 127 do
|
|
||||||
local al = lm + 3
|
|
||||||
local pfx = blk:sub(i, i + al - 1)
|
|
||||||
if #pfx ~= al then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local p = blockCache[bid]:find(pfx, 1, true)
|
|
||||||
if not p then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local score = al / 3
|
|
||||||
if score > bestScore then
|
|
||||||
bestData = string.char(bid) .. string.char((lm * 2) + math.floor((p - 1) / 256)) .. string.char((p - 1) % 256)
|
|
||||||
bestRes = pfx
|
|
||||||
bestScore = score
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- ok, encode!
|
|
||||||
io.write(bestData)
|
|
||||||
blockCache[blockIndex] = blockCache[blockIndex] .. bestRes
|
|
||||||
i = i + #bestRes
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
while 1 do
|
|
||||||
local blkd = io.read(512)
|
|
||||||
runBlock(blkd)
|
|
||||||
if #blkd < 512 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,73 +0,0 @@
|
|||||||
-- This is released into the public domain. XX
|
|
||||||
-- No warranty is provided, implied or otherwise. XX
|
|
||||||
local sector = io.write -- XX
|
|
||||||
-- BUNDIVIDE reference implementation for integration XX
|
|
||||||
local Cs,Cbu,Cb,Cw,Cp,Ct,Ci,CP,CB,CD={},128,"",128,"",""
|
|
||||||
CP = function(d,b)
|
|
||||||
Ct = Ct .. d
|
|
||||||
while#Ct>2 do
|
|
||||||
b = Ct:byte()
|
|
||||||
Ct = Ct:sub(2)
|
|
||||||
if b == 127 then
|
|
||||||
b = Ct:byte()
|
|
||||||
Ct = Ct:sub(2)
|
|
||||||
if b == 127 then
|
|
||||||
b = Ct:byte()+254
|
|
||||||
if b > 255then
|
|
||||||
b = b - 256
|
|
||||||
end
|
|
||||||
Ct = Ct:sub(2)
|
|
||||||
else
|
|
||||||
b = b + 127
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Cp = Cp..string.char(b)
|
|
||||||
if #Cp == 512 then
|
|
||||||
sector(Cp)
|
|
||||||
Cp = ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for i = 128, 127 + Cbu do
|
|
||||||
Cs[i] = ("\x00"):rep(512)
|
|
||||||
end
|
|
||||||
Cs[Cw] = ""
|
|
||||||
CB = function (d, i, d2, x, y)
|
|
||||||
i=1
|
|
||||||
while i <= #d - 2 do
|
|
||||||
b=d:byte(i)
|
|
||||||
d2=d:sub(i,i)
|
|
||||||
i=i+1
|
|
||||||
if not Ci then
|
|
||||||
if b==0then
|
|
||||||
Ci=1
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if b >= 128 then
|
|
||||||
x = d:byte(i)
|
|
||||||
i = i + 1
|
|
||||||
y=d:byte(i) + ((x % 2) * 256)
|
|
||||||
i = i + 1
|
|
||||||
d2=Cs[b]:sub(y + 1,y + 3 + math.floor(x / 2))
|
|
||||||
end
|
|
||||||
Cs[Cw]=Cs[Cw]..d2
|
|
||||||
if #Cs[Cw]>=512 then
|
|
||||||
CP(Cs[Cw])
|
|
||||||
Cw=((Cw-127)%Cbu)+128
|
|
||||||
Cs[Cw]=""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return i
|
|
||||||
end
|
|
||||||
CD = function(d)
|
|
||||||
Cb = Cb .. d
|
|
||||||
Cb = Cb:sub(CB(Cb))
|
|
||||||
end
|
|
||||||
CD(io.read("*a")) -- XX
|
|
||||||
--D.remove("init-bdivide.lua")--
|
|
||||||
--D.rename("init.lua","init-bdivide.lua")--
|
|
||||||
--local Ch=D.open("init-bdivide.lua","rb")--
|
|
||||||
--dieCB=function()D.close(Ch)D.remove("init-bdivide.lua")end--
|
|
||||||
--while true do local t=D.read(Ch, 64)if not t then break end CD(t)end--
|
|
||||||
CD("\x00\x00")CP(Cs[Cw] .. "\x00\x00")
|
|
@ -1,20 +0,0 @@
|
|||||||
-- PREPROC: preprocess input to be 7-bit
|
|
||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local c = io.read(1)
|
|
||||||
if not c then return end
|
|
||||||
local bc = c:byte()
|
|
||||||
if bc < 127 then
|
|
||||||
io.write(c)
|
|
||||||
else
|
|
||||||
if bc <= 253 then
|
|
||||||
-- 127(0) through 253(126)
|
|
||||||
io.write("\x7F" .. string.char(bc - 127))
|
|
||||||
else
|
|
||||||
-- 254(0) through 255 (1)
|
|
||||||
io.write("\x7F\x7F" .. string.char(bc - 254))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,4 +1,11 @@
|
|||||||
-- KittenOS NEO Repository Compliance Check Tool
|
-- KittenOS NEO Repository Compliance Check Tool
|
||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
-- I'm still not a lawyer
|
-- I'm still not a lawyer
|
||||||
local filesAccountedFor = {
|
local filesAccountedFor = {
|
||||||
["repository/data/app-claw/local.lua"] = 0,
|
["repository/data/app-claw/local.lua"] = 0,
|
||||||
|
27
heroes.lua
27
heroes.lua
@ -1,27 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- arg is the size of the code.tar file
|
|
||||||
local arg = ...
|
|
||||||
os.execute("lua com2/preproc.lua < code.tar | lua com2/bdivide.lua > com2/code.tar.bd")
|
|
||||||
os.execute("cat insthead.lua")
|
|
||||||
print("sC=" .. math.ceil(tonumber(arg) / 512))
|
|
||||||
local src = io.open("com2/bundiv.lua", "r")
|
|
||||||
while true do
|
|
||||||
local line = src:read()
|
|
||||||
if not line then
|
|
||||||
io.flush()
|
|
||||||
src:close()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local endix = line:sub(#line-1,#line)
|
|
||||||
if endix ~= "XX" then
|
|
||||||
if endix == "--" then
|
|
||||||
-- included
|
|
||||||
print(line:sub(3,#line-2))
|
|
||||||
else
|
|
||||||
print(line)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- XX means ignored.
|
|
||||||
end
|
|
34
imitclaw.lua
34
imitclaw.lua
@ -1,34 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- Imitation CLAW
|
|
||||||
local done = {}
|
|
||||||
|
|
||||||
local f, e = loadfile("code/data/app-claw/local.lua")
|
|
||||||
if not f then error(e) end
|
|
||||||
f = f()
|
|
||||||
if not os.execute("mkdir work") then
|
|
||||||
error("Delete 'work'")
|
|
||||||
end
|
|
||||||
for k, v in pairs(f) do
|
|
||||||
for _, vd in ipairs(v.dirs) do
|
|
||||||
os.execute("mkdir work/" .. vd .. " 2> /dev/null")
|
|
||||||
end
|
|
||||||
for _, vf in ipairs(v.files) do
|
|
||||||
-- not totally proofed but will do
|
|
||||||
if not os.execute("cp code/" .. vf .. " work/" .. vf) then
|
|
||||||
error("Could not copy " .. vf .. " in " .. k)
|
|
||||||
end
|
|
||||||
if done[vf] then
|
|
||||||
error("duplicate " .. vf .. " in " .. k)
|
|
||||||
end
|
|
||||||
print(vf .. "\t\t" .. k)
|
|
||||||
done[vf] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
os.execute("mkdir -p work/data/app-claw")
|
|
||||||
os.execute("cp code/data/app-claw/local.lua work/data/app-claw/local.lua")
|
|
||||||
os.execute("cd code ; find . > ../imitclaw.treecode")
|
|
||||||
os.execute("cd work ; find . > ../imitclaw.treework")
|
|
||||||
os.execute("diff -u imitclaw.treecode imitclaw.treework")
|
|
||||||
os.execute("rm imitclaw.treecode imitclaw.treework")
|
|
40
inst/bdivide/bga.lua
Normal file
40
inst/bdivide/bga.lua
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
local bga = {}
|
||||||
|
|
||||||
|
local str = io.read("*a")
|
||||||
|
|
||||||
|
for i = 1, #str - 1 do
|
||||||
|
local bg = str:sub(i, i + 1)
|
||||||
|
bga[bg] = (bga[bg] or 0) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local first = {}
|
||||||
|
local second = {}
|
||||||
|
|
||||||
|
local mode = ...
|
||||||
|
|
||||||
|
for k, v in pairs(bga) do
|
||||||
|
if mode == "combined" then
|
||||||
|
print(string.format("%08i: %02x%02x : %s", v, k:byte(1), k:byte(2), k))
|
||||||
|
end
|
||||||
|
first[k:sub(1, 1)] = (first[k:sub(1, 1)] or 0) + v
|
||||||
|
second[k:sub(1, 1)] = (second[k:sub(1, 1)] or 0) + v
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(first) do
|
||||||
|
if mode == "first" then
|
||||||
|
print(string.format("%08i: %s", v, k))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(second) do
|
||||||
|
if mode == "second" then
|
||||||
|
print(string.format("%08i: %s", v, k))
|
||||||
|
end
|
||||||
|
end
|
89
inst/bdivide/compress.lua
Normal file
89
inst/bdivide/compress.lua
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- PREPROC (r9 edition): preprocess input to be 7-bit
|
||||||
|
|
||||||
|
local frw = require("libs.frw")
|
||||||
|
|
||||||
|
local
|
||||||
|
-- SHARED WITH DECOMPRESSION ENGINE
|
||||||
|
function p(x, y)
|
||||||
|
if x == 126 then
|
||||||
|
return string.char(y), 3
|
||||||
|
elseif x == 127 then
|
||||||
|
return string.char(128 + y), 3
|
||||||
|
elseif x >= 32 then
|
||||||
|
return string.char(x), 2
|
||||||
|
elseif x == 31 then
|
||||||
|
return "\n", 2
|
||||||
|
elseif x == 30 then
|
||||||
|
return "\x00", 2
|
||||||
|
end
|
||||||
|
return string.char(("enart"):byte(x % 5 + 1), ("ndtelh"):byte((x - x % 5) / 5 + 1)), 2
|
||||||
|
end
|
||||||
|
|
||||||
|
local preprocParts = {}
|
||||||
|
local preprocMaxLen = 0
|
||||||
|
for i = 0, 127 do
|
||||||
|
for j = 0, 127 do
|
||||||
|
local d, l = p(i, j)
|
||||||
|
if d then
|
||||||
|
preprocMaxLen = math.max(preprocMaxLen, #d)
|
||||||
|
l = l - 1
|
||||||
|
if (not preprocParts[d]) or (#preprocParts[d] > l) then
|
||||||
|
if l == 2 then
|
||||||
|
preprocParts[d] = string.char(i, j)
|
||||||
|
else
|
||||||
|
preprocParts[d] = string.char(i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function preprocWithPadding(blk, p)
|
||||||
|
local out = ""
|
||||||
|
local needsPadding = false
|
||||||
|
while blk ~= "" do
|
||||||
|
p(blk)
|
||||||
|
local len = math.min(preprocMaxLen, #blk)
|
||||||
|
while len > 0 do
|
||||||
|
local seg = blk:sub(1, len)
|
||||||
|
if preprocParts[seg] then
|
||||||
|
out = out .. preprocParts[seg]
|
||||||
|
needsPadding = #preprocParts[seg] < 2
|
||||||
|
blk = blk:sub(#seg + 1)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
len = len - 1
|
||||||
|
end
|
||||||
|
assert(len ~= 0)
|
||||||
|
end
|
||||||
|
-- This needsPadding bit is just sort of quickly added in
|
||||||
|
-- to keep this part properly maintained
|
||||||
|
-- even though it might never get used
|
||||||
|
if needsPadding then
|
||||||
|
return out .. "\x00"
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local bdCore = require("bdivide.core")
|
||||||
|
|
||||||
|
return function (data, lexCrunch)
|
||||||
|
io.stderr:write("preproc: ")
|
||||||
|
local pi = frw.progress()
|
||||||
|
local function p(b)
|
||||||
|
pi(1 - (#b / #data))
|
||||||
|
end
|
||||||
|
data = preprocWithPadding(data, p)
|
||||||
|
io.stderr:write("\nbdivide: ")
|
||||||
|
pi = frw.progress()
|
||||||
|
data = bdCore.bdividePad(bdCore.bdivide(data, p))
|
||||||
|
io.stderr:write("\n")
|
||||||
|
return lexCrunch.process(frw.read("bdivide/instdeco.lua"), {}), data
|
||||||
|
end
|
76
inst/bdivide/core.lua
Normal file
76
inst/bdivide/core.lua
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- BDIVIDE r5 edition
|
||||||
|
-- Algorithm simplified for smaller implementation and potentially better compression
|
||||||
|
-- format:
|
||||||
|
-- 0-127 for constants
|
||||||
|
-- <128 + (length - 4)>, <position high>, <position low>
|
||||||
|
-- Position is where in the window it was found, minus 1.
|
||||||
|
-- windowSize must be the same between the encoder and decoder,
|
||||||
|
-- and is the amount of data preserved after cropping.
|
||||||
|
|
||||||
|
local bdivCore = {}
|
||||||
|
|
||||||
|
function bdivCore.bdivide(blk, p)
|
||||||
|
local out = ""
|
||||||
|
|
||||||
|
local windowSize = 0x10000
|
||||||
|
local windowData = ("\x00"):rep(windowSize)
|
||||||
|
|
||||||
|
while blk ~= "" do
|
||||||
|
p(blk)
|
||||||
|
local bestData = blk:sub(1, 1)
|
||||||
|
assert(blk:byte() < 128, "BDIVIDE does not handle 8-bit data")
|
||||||
|
local bestRes = bestData
|
||||||
|
for lm = 0, 127 do
|
||||||
|
local al = lm + 4
|
||||||
|
local pfx = blk:sub(1, al)
|
||||||
|
if #pfx ~= al then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local p = windowData:find(pfx, 1, true)
|
||||||
|
if not p then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local pm = p - 1
|
||||||
|
local thirdByte = pm % 256
|
||||||
|
bestData = string.char(128 + lm, math.floor(pm / 256), thirdByte)
|
||||||
|
bestRes = pfx
|
||||||
|
end
|
||||||
|
-- ok, encode!
|
||||||
|
out = out .. bestData
|
||||||
|
-- crop window
|
||||||
|
windowData = (windowData .. bestRes):sub(-windowSize)
|
||||||
|
blk = blk:sub(#bestRes + 1)
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Adds padding if required
|
||||||
|
function bdivCore.bdividePad(data)
|
||||||
|
local i = 1
|
||||||
|
-- Basically, if it ends on a literal,
|
||||||
|
-- then the literal won't get read without two padding bytes.
|
||||||
|
-- Otherwise (including if no data) it's fine.
|
||||||
|
local needsPadding = false
|
||||||
|
while i <= #data do
|
||||||
|
if data:byte(i) > 127 then
|
||||||
|
i = i + 3
|
||||||
|
needsPadding = false
|
||||||
|
else
|
||||||
|
i = i + 1
|
||||||
|
needsPadding = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if needsPadding then
|
||||||
|
return data .. "\x00\x00"
|
||||||
|
end
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
return bdivCore
|
68
inst/bdivide/instdeco.lua
Normal file
68
inst/bdivide/instdeco.lua
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- BDIVIDE (r5 edition) and PREPROC (r9 edition)
|
||||||
|
-- decompression engine for installer
|
||||||
|
|
||||||
|
$bdPPBuffer = ""
|
||||||
|
$bdBDBuffer = ""
|
||||||
|
$bdBDWindow = ("\x00"):rep(2^16)
|
||||||
|
-- High-level breakdown:
|
||||||
|
-- q is unescaper.
|
||||||
|
-- It'll only begin to input if at least 3 bytes are available,
|
||||||
|
-- so you'll want to throw in 2 extra zeroes at the end of stream as done here.
|
||||||
|
-- It uses t (input buffer) and p (output buffer).
|
||||||
|
-- Ignore its second argument, as that's a lie, it's just there for a local.
|
||||||
|
-- L is the actual decompressor. It has the same quirk as q, wanting two more bytes.
|
||||||
|
-- It stores to c (compressed), and w (window).
|
||||||
|
-- It outputs that which goes to the window to q also.
|
||||||
|
-- And it also uses a fake local.
|
||||||
|
|
||||||
|
-- SEE compress.lua FOR THIS FUNCTION
|
||||||
|
function $bdPP(x, y)
|
||||||
|
if x == 126 then
|
||||||
|
return string.char(y), 3
|
||||||
|
elseif x == 127 then
|
||||||
|
return string.char(128 + y), 3
|
||||||
|
elseif x >= 32 then
|
||||||
|
return string.char(x), 2
|
||||||
|
elseif x == 31 then
|
||||||
|
return "\n", 2
|
||||||
|
elseif x == 30 then
|
||||||
|
return "\x00", 2
|
||||||
|
end
|
||||||
|
return string.char(("enart"):byte(x % 5 + 1), ("ndtelh"):byte((x - x % 5) / 5 + 1)), 2
|
||||||
|
end
|
||||||
|
|
||||||
|
${
|
||||||
|
function $engineInput($L|lData)
|
||||||
|
$bdBDBuffer = $bdBDBuffer .. $lData
|
||||||
|
while #$bdBDBuffer > 2 do
|
||||||
|
$lData = $bdBDBuffer:byte()
|
||||||
|
if $lData < 128 then
|
||||||
|
$lData = $bdBDBuffer:sub(1, 1)
|
||||||
|
$bdBDBuffer = $bdBDBuffer:sub(2)
|
||||||
|
else
|
||||||
|
${
|
||||||
|
$L|bdBDPtr = $bdBDBuffer:byte(2) * 256 + $bdBDBuffer:byte(3) + 1
|
||||||
|
$lData = $bdBDWindow:sub($bdBDPtr, $bdBDPtr + $lData - 125)
|
||||||
|
$bdBDBuffer = $bdBDBuffer:sub(4)
|
||||||
|
$}
|
||||||
|
end
|
||||||
|
$bdPPBuffer = $bdPPBuffer .. $lData
|
||||||
|
$bdBDWindow = ($bdBDWindow .. $lData):sub(-2^16)
|
||||||
|
while #$bdPPBuffer > 1 do
|
||||||
|
${
|
||||||
|
$lData, $L|bdPPAdv = $bdPP($bdPPBuffer:byte(), $bdPPBuffer:byte(2))
|
||||||
|
$bdPPBuffer = $bdPPBuffer:sub($bdPPAdv)
|
||||||
|
$}
|
||||||
|
$engineOutput($lData)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
22
inst/bdvlite/compress.lua
Normal file
22
inst/bdvlite/compress.lua
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
local frw = require("libs.frw")
|
||||||
|
|
||||||
|
local bdCore = require("bdivide.core")
|
||||||
|
|
||||||
|
return function (data, lexCrunch)
|
||||||
|
io.stderr:write("\nbdivide: ")
|
||||||
|
local pi = frw.progress()
|
||||||
|
local function p(b)
|
||||||
|
pi(1 - (#b / #data))
|
||||||
|
end
|
||||||
|
data = bdCore.bdividePad(bdCore.bdivide(data, p))
|
||||||
|
io.stderr:write("\n")
|
||||||
|
return lexCrunch.process(frw.read("bdvlite/instdeco.lua"), {}), data
|
||||||
|
end
|
||||||
|
|
76
inst/bdvlite/core.lua
Normal file
76
inst/bdvlite/core.lua
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- BDIVIDE r5 edition
|
||||||
|
-- Algorithm simplified for smaller implementation and potentially better compression
|
||||||
|
-- format:
|
||||||
|
-- 0-127 for constants
|
||||||
|
-- <128 + (length - 4)>, <position high>, <position low>
|
||||||
|
-- Position is where in the window it was found, minus 1.
|
||||||
|
-- windowSize must be the same between the encoder and decoder,
|
||||||
|
-- and is the amount of data preserved after cropping.
|
||||||
|
|
||||||
|
local bdivCore = {}
|
||||||
|
|
||||||
|
function bdivCore.bdivide(blk, p)
|
||||||
|
local out = ""
|
||||||
|
|
||||||
|
local windowSize = 0x10000
|
||||||
|
local windowData = ("\x00"):rep(windowSize)
|
||||||
|
|
||||||
|
while blk ~= "" do
|
||||||
|
p(blk)
|
||||||
|
local bestData = blk:sub(1, 1)
|
||||||
|
assert(blk:byte() < 128, "BDIVIDE does not handle 8-bit data")
|
||||||
|
local bestRes = bestData
|
||||||
|
for lm = 0, 127 do
|
||||||
|
local al = lm + 4
|
||||||
|
local pfx = blk:sub(1, al)
|
||||||
|
if #pfx ~= al then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local p = windowData:find(pfx, 1, true)
|
||||||
|
if not p then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local pm = p - 1
|
||||||
|
local thirdByte = pm % 256
|
||||||
|
bestData = string.char(128 + lm, math.floor(pm / 256), thirdByte)
|
||||||
|
bestRes = pfx
|
||||||
|
end
|
||||||
|
-- ok, encode!
|
||||||
|
out = out .. bestData
|
||||||
|
-- crop window
|
||||||
|
windowData = (windowData .. bestRes):sub(-windowSize)
|
||||||
|
blk = blk:sub(#bestRes + 1)
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Adds padding if required
|
||||||
|
function bdivCore.bdividePad(data)
|
||||||
|
local i = 1
|
||||||
|
-- Basically, if it ends on a literal,
|
||||||
|
-- then the literal won't get read without two padding bytes.
|
||||||
|
-- Otherwise (including if no data) it's fine.
|
||||||
|
local needsPadding = false
|
||||||
|
while i <= #data do
|
||||||
|
if data:byte(i) > 127 then
|
||||||
|
i = i + 3
|
||||||
|
needsPadding = false
|
||||||
|
else
|
||||||
|
i = i + 1
|
||||||
|
needsPadding = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if needsPadding then
|
||||||
|
return data .. "\x00\x00"
|
||||||
|
end
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
return bdivCore
|
34
inst/bdvlite/instdeco.lua
Normal file
34
inst/bdvlite/instdeco.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- BDIVIDE (r5 edition)
|
||||||
|
-- decompression engine used to decompress DEFLATE decompression engine
|
||||||
|
|
||||||
|
$bdBDBuffer = ""
|
||||||
|
$bdBDWindow = ("\x00"):rep(2^16)
|
||||||
|
|
||||||
|
${
|
||||||
|
function $engineInput($L|lData)
|
||||||
|
$bdBDBuffer = $bdBDBuffer .. $lData
|
||||||
|
while #$bdBDBuffer > 2 do
|
||||||
|
$lData = $bdBDBuffer:byte()
|
||||||
|
if $lData < 128 then
|
||||||
|
$lData = $bdBDBuffer:sub(1, 1)
|
||||||
|
$bdBDBuffer = $bdBDBuffer:sub(2)
|
||||||
|
else
|
||||||
|
${
|
||||||
|
$L|bdBDPtr = $bdBDBuffer:byte(2) * 256 + $bdBDBuffer:byte(3) + 1
|
||||||
|
$lData = $bdBDWindow:sub($bdBDPtr, $bdBDPtr + $lData - 125)
|
||||||
|
$bdBDBuffer = $bdBDBuffer:sub(4)
|
||||||
|
$}
|
||||||
|
end
|
||||||
|
$bdBDWindow = ($bdBDWindow .. $lData):sub(-2^16)
|
||||||
|
$engineOutput($lData)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
82
inst/build.lua
Normal file
82
inst/build.lua
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- KittenOS NEO Installer Generator --
|
||||||
|
local args = {...}
|
||||||
|
|
||||||
|
local cid = args[1]
|
||||||
|
local tarName = args[2]
|
||||||
|
local algorithmsInReverseOrder = {}
|
||||||
|
for i = 3, #args do
|
||||||
|
table.insert(algorithmsInReverseOrder, 1, args[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
local u = require("libs.frw")
|
||||||
|
|
||||||
|
local instSize = 0
|
||||||
|
local function put(data)
|
||||||
|
io.write(data)
|
||||||
|
instSize = instSize + #data
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Installer Lexcrunch Context --
|
||||||
|
local lexCrunch = require("libs.lexcrunch")()
|
||||||
|
|
||||||
|
-- Installer Core --
|
||||||
|
|
||||||
|
-- installerFinalized:
|
||||||
|
-- Stuff that's already finished and put at the end of RISM. Prepend to this.
|
||||||
|
-- installerPayload / installerProgramLength:
|
||||||
|
-- The next-outer chunk that hasn't been written to the end of RISM
|
||||||
|
-- as the compression scheme (if one) has not been applied yet.
|
||||||
|
-- Really, installerProgramLength is only necessary because of the innermost chunk,
|
||||||
|
-- as that chunk has the TAR; additional data that's part of the same effective compression block,
|
||||||
|
-- but requires the program length to avoid it.
|
||||||
|
local installerPayload
|
||||||
|
local installerProgramLength
|
||||||
|
local installerFinalized = ""
|
||||||
|
|
||||||
|
do
|
||||||
|
local tarData = u.read(tarName)
|
||||||
|
local tarSectors = math.floor(#tarData / 512)
|
||||||
|
local installerCore = lexCrunch.process(u.read("instcore.lua"), {["$$SECTORS"] = tostring(tarSectors)})
|
||||||
|
installerPayload = installerCore .. tarData
|
||||||
|
installerProgramLength = #installerCore
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Installer Compression --
|
||||||
|
for _, v in ipairs(algorithmsInReverseOrder) do
|
||||||
|
io.stderr:write("compressing (" .. v .. ")\n")
|
||||||
|
local algImpl = require(v .. ".compress")
|
||||||
|
local algEngine, algData = algImpl(installerPayload, lexCrunch)
|
||||||
|
io.stderr:write("result: " .. #installerPayload .. " -> " .. #algData .. "\n")
|
||||||
|
-- prepend the program length of the last section
|
||||||
|
algEngine = lexCrunch.process("$iBlockingLen = " .. installerProgramLength .. " " .. algEngine, {})
|
||||||
|
-- commit
|
||||||
|
installerPayload = algEngine
|
||||||
|
installerProgramLength = #installerPayload
|
||||||
|
installerFinalized = algData .. installerFinalized
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Installer Final --
|
||||||
|
|
||||||
|
-- This is a special case, so the program length/payload/etc. business has to be repeated.
|
||||||
|
put("--" .. cid .. "\n")
|
||||||
|
put("--This is released into the public domain. No warranty is provided, implied or otherwise.\n")
|
||||||
|
put(lexCrunch.process(u.read("insthead.lua"), {["$$CORESIZE"] = tostring(installerProgramLength)}))
|
||||||
|
|
||||||
|
local RISM = installerPayload .. installerFinalized
|
||||||
|
RISM = RISM:gsub("\xFE", "\xFE\xFE")
|
||||||
|
RISM = RISM:gsub("]]", "]\xFE]")
|
||||||
|
RISM = "\x00" .. RISM
|
||||||
|
put("--[[" .. RISM .. "]]")
|
||||||
|
|
||||||
|
-- Dumping debug info --
|
||||||
|
local dbg = io.open("iSymTab", "wb")
|
||||||
|
lexCrunch.dump(dbg)
|
||||||
|
dbg:close()
|
||||||
|
|
18
inst/deflate/compress.lua
Normal file
18
inst/deflate/compress.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- This is a wrapper around (i.e. does not contain) Zopfli.
|
||||||
|
local frw = require("libs.frw")
|
||||||
|
|
||||||
|
return function (data, lexCrunch)
|
||||||
|
frw.write("tempData.bin", data)
|
||||||
|
os.execute("zopfli --i1 --deflate -c tempData.bin > tempZopf.bin")
|
||||||
|
local res = frw.read("tempZopf.bin")
|
||||||
|
os.execute("rm tempData.bin tempZopf.bin")
|
||||||
|
return lexCrunch.process(frw.read("deflate/instdeco.lua"), {}), res
|
||||||
|
end
|
||||||
|
|
291
inst/deflate/instdeco.lua
Normal file
291
inst/deflate/instdeco.lua
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- THIS NEXT LINE IS CLEARLY AWFUL
|
||||||
|
$bdBDWindow = nil
|
||||||
|
|
||||||
|
-- THE DEFLATE DECOMPRESSOR OF MADNESS --
|
||||||
|
|
||||||
|
-- Core I/O --
|
||||||
|
|
||||||
|
-- $dfAlignToByteRemaining is
|
||||||
|
-- set to 8 in the outer engine
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfGetIntField($L|lLen, $L|lVal)
|
||||||
|
$lVal = 0
|
||||||
|
for $L|lI = 0, $lLen - 1 do
|
||||||
|
if coroutine.yield() then
|
||||||
|
$lVal = $lVal + 2^$lI
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return $lVal
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- Huffman Core --
|
||||||
|
-- The approach here is based around 1-prefixed integers.
|
||||||
|
-- These are stored in a flat table.
|
||||||
|
-- So 0b1000 is the pattern 000.
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfReadHuffmanSymbol($L|lTree, $L|lVal)
|
||||||
|
$lVal = 1
|
||||||
|
while not $lTree[$lVal] do
|
||||||
|
$lVal = ($lVal * 2) + $dfGetIntField(1)
|
||||||
|
end
|
||||||
|
return $lTree[$lVal]
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfGenHuffmanTree($L|lCodeLens)
|
||||||
|
-- $L|lI (used everywhere; defining inside creates a bug because it gets globalized)
|
||||||
|
$L|lNextCode = {}
|
||||||
|
${
|
||||||
|
-- To explain:
|
||||||
|
-- lNextCode is needed all the way to the end.
|
||||||
|
-- But lBLCount isn't needed after it's used to
|
||||||
|
-- generate lNextCode.
|
||||||
|
-- And lCode is very, very temporary.
|
||||||
|
-- Hence this massive block.
|
||||||
|
$L|lBLCount = {}
|
||||||
|
-- Note the 0
|
||||||
|
for $lI = 0, 15 do
|
||||||
|
$lBLCount[$lI] = 0
|
||||||
|
end
|
||||||
|
for $lI = 0, #$lCodeLens do
|
||||||
|
${
|
||||||
|
$L|lCodeLen = $lCodeLens[$lI]
|
||||||
|
if $lCodeLen ~= 0 then
|
||||||
|
$lBLCount[$lCodeLen] = $lBLCount[$lCodeLen] + 1
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
end
|
||||||
|
|
||||||
|
$L|lCode = 0
|
||||||
|
for $lI = 1, 15 do
|
||||||
|
$lCode = ($lCode + $lBLCount[$lI - 1]) * 2
|
||||||
|
$lNextCode[$lI] = $lCode
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
$L|lTree = {}
|
||||||
|
for $lI = 0, #$lCodeLens do
|
||||||
|
${
|
||||||
|
$L|lCodeLen = $lCodeLens[$lI]
|
||||||
|
if $lCodeLen ~= 0 then
|
||||||
|
$L|lPow = math.floor(2 ^ $lCodeLen)
|
||||||
|
assert($lNextCode[$lCodeLen] < $lPow, "Tl" .. $lCodeLen)
|
||||||
|
$L|lK = $lNextCode[$lCodeLen] + $lPow
|
||||||
|
assert(not $lTree[$lK], "conflict @ " .. $lK)
|
||||||
|
$lTree[$lK] = $lI
|
||||||
|
$lNextCode[$lCodeLen] = $lNextCode[$lCodeLen] + 1
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
end
|
||||||
|
return $lTree
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- DEFLATE fixed trees --
|
||||||
|
${
|
||||||
|
$L|dfFixedTL = {}
|
||||||
|
for $L|lI = 0, 143 do $dfFixedTL[$lI] = 8 end
|
||||||
|
for $lI = 144, 255 do $dfFixedTL[$lI] = 9 end
|
||||||
|
for $lI = 256, 279 do $dfFixedTL[$lI] = 7 end
|
||||||
|
for $lI = 280, 287 do $dfFixedTL[$lI] = 8 end
|
||||||
|
$dfFixedLit = $dfGenHuffmanTree($dfFixedTL)
|
||||||
|
-- last line possibly destroyed dfFixedTL, but that's alright
|
||||||
|
$dfFixedTL = {}
|
||||||
|
for $lI = 0, 31 do $dfFixedTL[$lI] = 5 end
|
||||||
|
$dfFixedDst = $dfGenHuffmanTree($dfFixedTL)
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- DEFLATE LZ Core --
|
||||||
|
|
||||||
|
$dfWindow = ("\x00"):rep(2^15)
|
||||||
|
$dfPushBuf = ""
|
||||||
|
${
|
||||||
|
function $dfOutput($L|lData)
|
||||||
|
$dfWindow = ($dfWindow .. $lData):sub(-2^15)
|
||||||
|
$dfPushBuf = $dfPushBuf .. $lData
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
$dfBittblLength = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 2, 2, 2, 2,
|
||||||
|
3, 3, 3, 3, 4, 4, 4, 4,
|
||||||
|
5, 5, 5, 5, 0
|
||||||
|
}
|
||||||
|
$dfBasetblLength = {
|
||||||
|
3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
|
11, 13, 15, 17, 19, 23, 27, 31,
|
||||||
|
35, 43, 51, 59, 67, 83, 99, 115,
|
||||||
|
131, 163, 195, 227, 258
|
||||||
|
}
|
||||||
|
$dfBittblDist = {
|
||||||
|
0, 0, 0, 0, 1, 1, 2, 2,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6,
|
||||||
|
7, 7, 8, 8, 9, 9, 10, 10,
|
||||||
|
11, 11, 12, 12, 13, 13
|
||||||
|
}
|
||||||
|
$dfBasetblDist = {
|
||||||
|
1, 2, 3, 4, 5, 7, 9, 13,
|
||||||
|
17, 25, 33, 49, 65, 97, 129, 193,
|
||||||
|
257, 385, 513, 769, 1025, 1537, 2049, 3073,
|
||||||
|
4097, 6145, 8193, 12289, 16385, 24577
|
||||||
|
}
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfReadBlockBody($L|lLit, $L|lDst, $L|lLitSym, $L|lLen, $L|lDCode, $L|lPtr)
|
||||||
|
while true do
|
||||||
|
$lLitSym = $dfReadHuffmanSymbol($lLit)
|
||||||
|
if $lLitSym <= 255 then
|
||||||
|
$dfOutput(string.char($lLitSym))
|
||||||
|
elseif $lLitSym == 256 then
|
||||||
|
return
|
||||||
|
elseif $lLitSym <= 285 then
|
||||||
|
$lLen = $dfBasetblLength[$lLitSym - 256] + $dfGetIntField($dfBittblLength[$lLitSym - 256])
|
||||||
|
$lDCode = $dfReadHuffmanSymbol($lDst)
|
||||||
|
$lPtr = 32769 - ($dfBasetblDist[$lDCode + 1] + $dfGetIntField($dfBittblDist[$lDCode + 1]))
|
||||||
|
for $L|lI = 1, $lLen do
|
||||||
|
$dfOutput($dfWindow:sub($lPtr, $lPtr))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("nt" .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- Huffman Dynamics --
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfReadHuffmanDynamicSubcodes($L|lDistLens, $L|lCount, $L|lMetatree, $L|lCode)
|
||||||
|
-- used a lot: $L|lI
|
||||||
|
$lCode = 0
|
||||||
|
$lDistLens[-1] = 0
|
||||||
|
while $lCode < $lCount do
|
||||||
|
-- use a tmpglb since it's just for the chain
|
||||||
|
$L|lInstr = $dfReadHuffmanSymbol($lMetatree)
|
||||||
|
if $lInstr < 16 then
|
||||||
|
$lDistLens[$lCode] = $lInstr
|
||||||
|
$lCode = $lCode + 1
|
||||||
|
elseif $lInstr == 16 then
|
||||||
|
for $lI = 1, 3 + $dfGetIntField(2) do
|
||||||
|
$lDistLens[$lCode] = $lDistLens[$lCode - 1]
|
||||||
|
$lCode = $lCode + 1
|
||||||
|
assert($lCode <= $lCount, "sc.over")
|
||||||
|
end
|
||||||
|
elseif $lInstr == 17 then
|
||||||
|
for $lI = 1, 3 + $dfGetIntField(3) do
|
||||||
|
$lDistLens[$lCode] = 0
|
||||||
|
$lCode = $lCode + 1
|
||||||
|
assert($lCode <= $lCount, "sc.over")
|
||||||
|
end
|
||||||
|
elseif $lInstr == 18 then
|
||||||
|
for $lI = 1, 11 + $dfGetIntField(7) do
|
||||||
|
$lDistLens[$lCode] = 0
|
||||||
|
$lCode = $lCode + 1
|
||||||
|
assert($lCode <= $lCount, "sc.over")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- is this even possible?
|
||||||
|
error("sc.unki")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$lDistLens[-1] = nil
|
||||||
|
return $lDistLens
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
$dfDynamicMetalensScramble = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
|
||||||
|
|
||||||
|
${
|
||||||
|
function $dfReadHuffmanDynamic($L|lState, $L|lLiteralSize, $L|lDistanceSize, $L|lDistanceLens)
|
||||||
|
-- $L|lI loop variable, used all over
|
||||||
|
-- to save on locals, this is reused
|
||||||
|
-- as metalens
|
||||||
|
$lState = {}
|
||||||
|
for $lI = 0, 18 do $lState[$lI] = 0 end
|
||||||
|
$lLiteralSize = $dfGetIntField(5) + 257
|
||||||
|
$lDistanceSize = $dfGetIntField(5) + 1
|
||||||
|
for $lI = 1, $dfGetIntField(4) + 4 do
|
||||||
|
$lState[$dfDynamicMetalensScramble[$lI]] = $dfGetIntField(3)
|
||||||
|
end
|
||||||
|
-- as metatree
|
||||||
|
$lState = $dfGenHuffmanTree($lState)
|
||||||
|
-- as concatenated subcodes
|
||||||
|
$lState = $dfReadHuffmanDynamicSubcodes({}, $lLiteralSize + $lDistanceSize, $lState)
|
||||||
|
-- The distance lengths are removed from lState,
|
||||||
|
-- while being added to lDistanceLens
|
||||||
|
-- The result is completion
|
||||||
|
$lDistanceLens = {}
|
||||||
|
for $lI = 0, $lDistanceSize - 1 do
|
||||||
|
$lDistanceLens[$lI] = $lState[$lLiteralSize + $lI]
|
||||||
|
$lState[$lLiteralSize + $lI] = nil
|
||||||
|
end
|
||||||
|
return $dfGenHuffmanTree($lState), $dfGenHuffmanTree($lDistanceLens)
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- Main Thread --
|
||||||
|
|
||||||
|
${
|
||||||
|
$dfThread = coroutine.create(function ($L|lFinal, $L|lLitLen)
|
||||||
|
while true do
|
||||||
|
$lFinal = coroutine.yield()
|
||||||
|
$L|lBlockType = $dfGetIntField(2)
|
||||||
|
if $lBlockType == 0 then
|
||||||
|
-- literal
|
||||||
|
$dfGetIntField($dfAlignToByteRemaining)
|
||||||
|
$lLitLen = $dfGetIntField(16)
|
||||||
|
-- this is weird, ignore it
|
||||||
|
$dfGetIntField(16)
|
||||||
|
for $L|lI = 1, $lLitLen do
|
||||||
|
$dfOutput(string.char($dfGetIntField(8)))
|
||||||
|
end
|
||||||
|
elseif $lBlockType == 1 then
|
||||||
|
-- fixed Huffman
|
||||||
|
$dfReadBlockBody($dfFixedLit, $dfFixedDst)
|
||||||
|
elseif $lBlockType == 2 then
|
||||||
|
-- dynamic Huffman
|
||||||
|
$dfReadBlockBody($dfReadHuffmanDynamic())
|
||||||
|
else
|
||||||
|
error("b3")
|
||||||
|
end
|
||||||
|
while $lFinal do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
$}
|
||||||
|
|
||||||
|
-- The Outer Engine --
|
||||||
|
|
||||||
|
coroutine.resume($dfThread)
|
||||||
|
${
|
||||||
|
function $engineInput($L|lData, $L|lByte)
|
||||||
|
for $L|lI = 1, #$lData do
|
||||||
|
$lByte = $lData:byte($lI)
|
||||||
|
$dfAlignToByteRemaining = 8
|
||||||
|
while $dfAlignToByteRemaining > 0 do
|
||||||
|
-- If we're providing the first bit (v = 8), then there are 7 bits remaining.
|
||||||
|
-- So this hits 0 when the *next* 8 yields will provide an as-is byte.
|
||||||
|
$dfAlignToByteRemaining = $dfAlignToByteRemaining - 1
|
||||||
|
assert(coroutine.resume($dfThread, $lByte % 2 == 1))
|
||||||
|
$lByte = math.floor($lByte / 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- flush prepared buffer
|
||||||
|
$engineOutput($dfPushBuf)
|
||||||
|
$dfPushBuf = ""
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
80
inst/instcore.lua
Normal file
80
inst/instcore.lua
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
-- KOSNEO installer base
|
||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
$icScreen = $component.list("screen", true)()
|
||||||
|
$icGPU = $component.list("gpu", true)()
|
||||||
|
|
||||||
|
$icFilename = "Starting..."
|
||||||
|
$icBytesRemaining = 0
|
||||||
|
|
||||||
|
if $icScreen and $icGPU then
|
||||||
|
$icGPU = $component.proxy($icGPU)
|
||||||
|
$icGPU.bind($icScreen)
|
||||||
|
$icGPU.setResolution(50, 5)
|
||||||
|
$icGPU.setBackground(2^24-1)
|
||||||
|
$icGPU.setForeground(0)
|
||||||
|
$icGPU.fill(1, 1, 50, 5, "█")
|
||||||
|
$icGPU.fill(1, 2, 50, 1, " ")
|
||||||
|
$icGPU.set(2, 2, "KittenOS NEO Installer")
|
||||||
|
end
|
||||||
|
|
||||||
|
function $icOctalToNumber($a0)
|
||||||
|
if $a0 == "" then return 0 end
|
||||||
|
return $icOctalToNumber($a0:sub(1, -2)) * 8 + ($a0:byte(#$a0) - 48)
|
||||||
|
end
|
||||||
|
|
||||||
|
$icSectorsRead = 0
|
||||||
|
$iBlockingLen = 512
|
||||||
|
function $iBlockingHook($a0)
|
||||||
|
if $icBytesRemaining > 0 then
|
||||||
|
${
|
||||||
|
$L|icByteAdv = math.min(512, $icBytesRemaining)
|
||||||
|
$icBytesRemaining = $icBytesRemaining - $icByteAdv
|
||||||
|
if $icFile then
|
||||||
|
$filesystem.write($icFile, $a0:sub(1, $icByteAdv))
|
||||||
|
if $icBytesRemaining <= 0 then
|
||||||
|
$filesystem.close($icFile)
|
||||||
|
$icFile = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
else
|
||||||
|
$icFilename = $a0:sub(1, 100):gsub("\x00", "")
|
||||||
|
-- this sets up the reading/skipping of data
|
||||||
|
$icBytesRemaining = $icOctalToNumber($a0:sub(125, 135))
|
||||||
|
if $icFilename:sub(1, 2) == "./" and $icFilename ~= "./" then
|
||||||
|
$icFilename = $icFilename:sub(3)
|
||||||
|
if $icFilename:sub(#$icFilename) == "/" then
|
||||||
|
$filesystem.makeDirectory($icFilename)
|
||||||
|
else
|
||||||
|
$icFile = $filesystem.open($icFilename, "wb")
|
||||||
|
if $icBytesRemaining == 0 then
|
||||||
|
$filesystem.close($icFile)
|
||||||
|
$icFile = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- UPDATE DISPLAY --
|
||||||
|
$icSectorsRead = $icSectorsRead + 1
|
||||||
|
if $icScreen and $icGPU then
|
||||||
|
$icGPU.fill(1, 2, 50, 1, " ")
|
||||||
|
$icGPU.set(2, 2, "KittenOS NEO Installer : " .. $icFilename)
|
||||||
|
$icGPU.fill(2, 4, 48, 1, "█")
|
||||||
|
$icGPU.fill(2, 4, math.ceil(48 * $icSectorsRead / $$SECTORS), 1, " ")
|
||||||
|
end
|
||||||
|
if $icSectorsRead % 16 == 0 then
|
||||||
|
$computer.pullSignal(0.01)
|
||||||
|
end
|
||||||
|
if $icSectorsRead == $$SECTORS then
|
||||||
|
$filesystem.close($readInFile)
|
||||||
|
$filesystem.remove("init.neoi.lua")
|
||||||
|
$computer.shutdown(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
71
inst/insthead.lua
Normal file
71
inst/insthead.lua
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
-- KOSNEO installer base
|
||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
$computer = computer
|
||||||
|
$component = component
|
||||||
|
assert($component, "KittenOS NEO installer: Copy as init.lua to the target disk, then remove other disks & reboot.")
|
||||||
|
|
||||||
|
$filesystem = $component.proxy($computer.getBootAddress())
|
||||||
|
|
||||||
|
$filesystem.remove("init.neoi.lua")
|
||||||
|
$filesystem.rename("init.lua", "init.neoi.lua")
|
||||||
|
$readInFile = $filesystem.open("init.neoi.lua", "rb")
|
||||||
|
|
||||||
|
$iBlockingBuffer = ""
|
||||||
|
$iBlockingLen = $$CORESIZE
|
||||||
|
${
|
||||||
|
function $iBlockingHook($L|lBlock)
|
||||||
|
-- Run the next script (replacement compression engine,)
|
||||||
|
assert(load($lBlock))()
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
|
||||||
|
${
|
||||||
|
function $engineOutput($L|lBlock)
|
||||||
|
$iBlockingBuffer = $iBlockingBuffer .. $lBlock
|
||||||
|
while #$iBlockingBuffer >= $iBlockingLen do
|
||||||
|
$lBlock = $iBlockingBuffer:sub(1, $iBlockingLen)
|
||||||
|
$iBlockingBuffer = $iBlockingBuffer:sub($iBlockingLen + 1)
|
||||||
|
$iBlockingHook($lBlock)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
$engineInput = $engineOutput
|
||||||
|
|
||||||
|
while true do
|
||||||
|
$readInBlock = $filesystem.read($readInFile, 1024)
|
||||||
|
${
|
||||||
|
for i = 1, #$readInBlock do
|
||||||
|
-- Read-in state machine
|
||||||
|
|
||||||
|
-- IT IS VERY IMPORTANT that read-in be performed char-by-char.
|
||||||
|
-- This is because of compression chain-loading; if the switch between engines isn't "clean",
|
||||||
|
-- bad stuff happens.
|
||||||
|
|
||||||
|
-- This character becomes invalid once
|
||||||
|
-- it gets passed to engineInput,
|
||||||
|
-- but that's the last step, so it's ok!
|
||||||
|
$L|readInChar = $readInBlock:sub(i, i)
|
||||||
|
if not $readInState then
|
||||||
|
if $readInChar == "\x00" then
|
||||||
|
$readInState = 0
|
||||||
|
end
|
||||||
|
elseif $readInState == 0 then
|
||||||
|
if $readInChar == "\xFE" then
|
||||||
|
$readInState = 1
|
||||||
|
else
|
||||||
|
$engineInput($readInChar)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
$engineInput($readInChar)
|
||||||
|
$readInState = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$}
|
||||||
|
end
|
||||||
|
|
34
inst/libs/frw.lua
Normal file
34
inst/libs/frw.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
return {
|
||||||
|
read = function (fn)
|
||||||
|
local f = io.open(fn, "rb")
|
||||||
|
local d = f:read("*a")
|
||||||
|
f:close()
|
||||||
|
return d
|
||||||
|
end,
|
||||||
|
write = function (fn, data)
|
||||||
|
local f = io.open(fn, "wb")
|
||||||
|
f:write(data)
|
||||||
|
f:close()
|
||||||
|
end,
|
||||||
|
progress = function ()
|
||||||
|
io.stderr:write("00% \\")
|
||||||
|
local lastPercent = 0
|
||||||
|
local chr = 0
|
||||||
|
return function (fraction)
|
||||||
|
local percent = math.ceil(fraction * 100)
|
||||||
|
if percent ~= lastPercent then
|
||||||
|
lastPercent = percent
|
||||||
|
chr = (chr + 1) % 4
|
||||||
|
io.stderr:write(string.format("\8\8\8\8\8%02i%% %s", percent, ("\\|/-"):sub(chr + 1, chr + 1)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
195
inst/libs/lexcrunch.lua
Normal file
195
inst/libs/lexcrunch.lua
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- This library helps in crunching down the installer a bit further.
|
||||||
|
local sequences = {
|
||||||
|
{"\n", " "},
|
||||||
|
{" ", " "},
|
||||||
|
{" #", "#"},
|
||||||
|
{"# ", "#"},
|
||||||
|
{" ,", ","},
|
||||||
|
{", ", ","},
|
||||||
|
{" (", "("},
|
||||||
|
{"( ", "("},
|
||||||
|
{" )", ")"},
|
||||||
|
{") ", ")"},
|
||||||
|
{" {", "{"},
|
||||||
|
{"{ ", "{"},
|
||||||
|
{" }", "}"},
|
||||||
|
{"} ", "}"},
|
||||||
|
{" <", "<"},
|
||||||
|
{"< ", "<"},
|
||||||
|
{" >", ">"},
|
||||||
|
{"> ", ">"},
|
||||||
|
{" *", "*"},
|
||||||
|
{"* ", "*"},
|
||||||
|
{" ~", "~"},
|
||||||
|
{"~ ", "~"},
|
||||||
|
{" /", "/"},
|
||||||
|
{"/ ", "/"},
|
||||||
|
{" %", "%"},
|
||||||
|
{"% ", "%"},
|
||||||
|
{" =", "="},
|
||||||
|
{"= ", "="},
|
||||||
|
{" -", "-"},
|
||||||
|
{"- ", "-"},
|
||||||
|
{" +", "+"},
|
||||||
|
{"+ ", "+"},
|
||||||
|
{".. ", ".."},
|
||||||
|
{" ..", ".."},
|
||||||
|
{"\"\" ", "\"\""},
|
||||||
|
{"=0 t", "=0t"},
|
||||||
|
{">0 t", ">0t"},
|
||||||
|
{">1 t", ">1t"},
|
||||||
|
{"=1 w", "=1w"},
|
||||||
|
{"=380 l", "=380l"},
|
||||||
|
{"=127 t", "=127t"},
|
||||||
|
{"<128 t", "<128t"},
|
||||||
|
{"=128 t", "=128t"},
|
||||||
|
{">255 t", ">255t"},
|
||||||
|
{"=512 t", "=512t"}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function pass(buffer)
|
||||||
|
local ob = ""
|
||||||
|
local smode = false
|
||||||
|
while #buffer > 0 do
|
||||||
|
if not smode then
|
||||||
|
local ds = true
|
||||||
|
while ds do
|
||||||
|
ds = false
|
||||||
|
for _, v in ipairs(sequences) do
|
||||||
|
if buffer:sub(1, #(v[1])) == v[1] then
|
||||||
|
buffer = v[2] .. buffer:sub(#(v[1]) + 1)
|
||||||
|
ds = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local ch = buffer:sub(1, 1)
|
||||||
|
buffer = buffer:sub(2)
|
||||||
|
ob = ob .. ch
|
||||||
|
if ch == "\"" then
|
||||||
|
smode = not smode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ob
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Context creation --
|
||||||
|
return function ()
|
||||||
|
local forwardSymTab = {}
|
||||||
|
local reverseSymTab = {}
|
||||||
|
|
||||||
|
local temporaryPool = {}
|
||||||
|
|
||||||
|
local stackFrames = {}
|
||||||
|
|
||||||
|
local log = {}
|
||||||
|
|
||||||
|
local possible = {}
|
||||||
|
for i = 1, 52 do
|
||||||
|
possible[i] = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"):sub(i, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function allocate(reason)
|
||||||
|
for _, v in pairs(possible) do
|
||||||
|
if not reverseSymTab[v] then
|
||||||
|
reverseSymTab[v] = reason
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function allocTmp(id)
|
||||||
|
assert(not forwardSymTab[id], "var already exists: " .. id)
|
||||||
|
local val = table.remove(temporaryPool, 1)
|
||||||
|
if not val then val = allocate("temporary") end
|
||||||
|
forwardSymTab[id] = val
|
||||||
|
table.insert(log, "allocTmp " .. id .. " -> " .. val)
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
|
||||||
|
local lexCrunch = {}
|
||||||
|
function lexCrunch.dump(file)
|
||||||
|
file:write("forward table:\n")
|
||||||
|
for k, v in pairs(forwardSymTab) do
|
||||||
|
file:write(k .. " -> " .. v .. "\n")
|
||||||
|
end
|
||||||
|
file:write("reverse table (where differing):\n")
|
||||||
|
for k, v in pairs(reverseSymTab) do
|
||||||
|
if forwardSymTab[v] ~= k then
|
||||||
|
file:write(v .. " -> " .. k .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
file:write("log:\n")
|
||||||
|
for k, v in ipairs(log) do
|
||||||
|
file:write(v .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function lexCrunch.process(op, defines)
|
||||||
|
-- symbol replacement
|
||||||
|
op = op:gsub("%$[%$a-z%{%}%|A-Z0-9]*", function (str)
|
||||||
|
if str:sub(2, 2) == "$" then
|
||||||
|
-- defines
|
||||||
|
assert(defines[str], "no define " .. str)
|
||||||
|
return defines[str]
|
||||||
|
end
|
||||||
|
local com = {}
|
||||||
|
for v in str:sub(2):gmatch("[^%|]*") do
|
||||||
|
table.insert(com, v)
|
||||||
|
end
|
||||||
|
if com[1] == "L" then
|
||||||
|
assert(#com == 2)
|
||||||
|
local id = "$" .. com[2]
|
||||||
|
assert(stackFrames[1], "allocation of " .. id .. " outside of stack frame")
|
||||||
|
table.insert(stackFrames[1], id)
|
||||||
|
return allocTmp(id)
|
||||||
|
elseif com[1] == "{" then
|
||||||
|
assert(#com == 1)
|
||||||
|
table.insert(stackFrames, 1, {})
|
||||||
|
return ""
|
||||||
|
elseif com[1] == "}" then
|
||||||
|
assert(#com == 1)
|
||||||
|
for _, id in ipairs(table.remove(stackFrames, 1)) do
|
||||||
|
table.insert(temporaryPool, forwardSymTab[id])
|
||||||
|
forwardSymTab[id] = nil
|
||||||
|
end
|
||||||
|
return ""
|
||||||
|
else
|
||||||
|
assert(#com == 1)
|
||||||
|
local id = "$" .. com[1]
|
||||||
|
-- normal handling
|
||||||
|
if forwardSymTab[id] then
|
||||||
|
return forwardSymTab[id]
|
||||||
|
end
|
||||||
|
local v = allocate(id)
|
||||||
|
forwardSymTab[id] = v
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
-- comment removal
|
||||||
|
while true do
|
||||||
|
local np = op:gsub("%-%-[^\n]*\n", " ")
|
||||||
|
np = np:gsub("%-%-[^\n]*$", "")
|
||||||
|
if np == op then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
op = np
|
||||||
|
end
|
||||||
|
-- stripping
|
||||||
|
while true do
|
||||||
|
local np = pass(op)
|
||||||
|
if np == op then
|
||||||
|
return np
|
||||||
|
end
|
||||||
|
op = np
|
||||||
|
end
|
||||||
|
return op
|
||||||
|
end
|
||||||
|
return lexCrunch
|
||||||
|
end
|
40
inst/status.lua
Normal file
40
inst/status.lua
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- Status Screen --
|
||||||
|
local target = ...
|
||||||
|
local u = require("libs.frw")
|
||||||
|
local instSize = #u.read(target)
|
||||||
|
|
||||||
|
local status = ""
|
||||||
|
local statusDetail = ""
|
||||||
|
local blinkI = ""
|
||||||
|
if instSize > 65536 then
|
||||||
|
blinkI = "5;31;"
|
||||||
|
status = " DO NOT SHIP "
|
||||||
|
statusDetail = "The installer is too big to ship safely.\nIt's possible it may crash on Tier 1 systems.\nUpgrade the compression system or remove existing code."
|
||||||
|
elseif instSize > 64000 then
|
||||||
|
blinkI = "33;"
|
||||||
|
status = " Shippable * "
|
||||||
|
statusDetail = "The installer is getting dangerously large.\nReserve further room for bugfixes."
|
||||||
|
else
|
||||||
|
blinkI = "32;"
|
||||||
|
status = " All Green "
|
||||||
|
statusDetail = "The installer is well within budget with room for features.\nDevelop as normal."
|
||||||
|
end
|
||||||
|
io.stderr:write("\n")
|
||||||
|
local ctS, ctM, ctE = " \x1b[1;" .. blinkI .. "7m", "\x1b[0;7m", "\x1b[0m\n"
|
||||||
|
io.stderr:write(ctS .. " " .. ctM .. " " .. ctE)
|
||||||
|
io.stderr:write(ctS .. status .. ctM .. string.format(" %07i ", 65536 - instSize) .. ctE)
|
||||||
|
io.stderr:write(ctS .. " " .. ctM .. " " .. ctE)
|
||||||
|
io.stderr:write("\n")
|
||||||
|
io.stderr:write(statusDetail .. "\n")
|
||||||
|
io.stderr:write("\n")
|
||||||
|
io.stderr:write("Size: " .. instSize .. "\n")
|
||||||
|
io.stderr:write(" max. 65536\n")
|
||||||
|
io.stderr:write("\n")
|
||||||
|
|
32
inst/symbolGuide.md
Normal file
32
inst/symbolGuide.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# The Symbol Guide
|
||||||
|
|
||||||
|
## lexCrunch commands
|
||||||
|
|
||||||
|
The following prefixes are really special,
|
||||||
|
and are lexcrunch's responsibility:
|
||||||
|
|
||||||
|
"$$THING" : These are defines.
|
||||||
|
"$Thing" : Writes a global into stream. If not already allocated, is allocated a global.
|
||||||
|
|
||||||
|
"${" : Opens a frame.
|
||||||
|
"$}" : Closes a frame. (Attached temps are released.)
|
||||||
|
"$L|THING" : Allocates THING from temp pool, attaches to stack frame, writes to stream.
|
||||||
|
Use inside a comment to erase the written symbol
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
The rest are convention:
|
||||||
|
"$iThing" symbols are Installer Wrapper.
|
||||||
|
"$icThing" symbols are Installer Core.
|
||||||
|
"$dfThing" symbols are DEFLATE Engine.
|
||||||
|
"$bdThing" symbols are BDIVIDE Engine.
|
||||||
|
|
||||||
|
"$a0", "$a1", etc. are Local Symbols.
|
||||||
|
DEPRECATED, THESE ARE AN OLD MECHANISM, USE FRAMED TEMPS INSTEAD.
|
||||||
|
These are reserved only for use in locals.
|
||||||
|
(For loops count.)
|
||||||
|
|
||||||
|
"$lThing" symbols are used to name Local Symbols using aliases.
|
||||||
|
|
||||||
|
NO THEY ARE NOW USED FOR ALL TEMPS, INCLUDING LOCAL SYMBOLS
|
||||||
|
|
14
inst/uncompressed/compress.lua
Normal file
14
inst/uncompressed/compress.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
-- THIS SOFTWARE.
|
||||||
|
|
||||||
|
-- Example compression engine.
|
||||||
|
-- Given: data, lexCrunch
|
||||||
|
-- returns compressionEngine, compressedData
|
||||||
|
return function (data, lexCrunch)
|
||||||
|
return lexCrunch.process(" $engineInput = $engineOutput ", {}), data
|
||||||
|
end
|
||||||
|
|
97
insthead.lua
97
insthead.lua
@ -1,97 +0,0 @@
|
|||||||
-- KOSNEO inst.
|
|
||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
C, O, G, D = component, computer
|
|
||||||
assert(C, "To install, please copy as init.lua to a blank disk or a system to update, then remove all other disks and reboot.")
|
|
||||||
|
|
||||||
sa = C.list("screen", true)()
|
|
||||||
if sa then
|
|
||||||
G = C.list("gpu", true)()
|
|
||||||
if G then
|
|
||||||
G = C.proxy(G)
|
|
||||||
G.bind(sa)
|
|
||||||
G.setForeground(0xFFFFFF)
|
|
||||||
G.setBackground(0x000000)
|
|
||||||
G.setResolution(50, 5)
|
|
||||||
G.setDepth(1)
|
|
||||||
G.fill(1, 1, 50, 5, " ")
|
|
||||||
G.setBackground(0xFFFFFF)
|
|
||||||
G.setForeground(0x000000)
|
|
||||||
G.fill(1, 2, 50, 1, " ")
|
|
||||||
G.set(2, 2, "KittenOS NEO Installer")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
D = C.proxy(O.getBootAddress())
|
|
||||||
|
|
||||||
tFN,tFSR,tW,tF="Starting...",0,0
|
|
||||||
|
|
||||||
function tO(oct)
|
|
||||||
local v = oct:byte(#oct) - 0x30
|
|
||||||
if #oct > 1 then
|
|
||||||
return (tO(oct:sub(1, #oct - 1)) * 8) + v
|
|
||||||
end
|
|
||||||
return v
|
|
||||||
end
|
|
||||||
function tA(s)
|
|
||||||
if tW > 0 then
|
|
||||||
tW = tW - 1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if tF then
|
|
||||||
local ta = math.min(512, tFSR)
|
|
||||||
D.write(tF, s:sub(1, ta))
|
|
||||||
tFSR = tFSR - ta
|
|
||||||
if tFSR == 0 then
|
|
||||||
D.close(tF)
|
|
||||||
tF = nil
|
|
||||||
end
|
|
||||||
else
|
|
||||||
tFN = s:sub(1, 100):gsub("\x00", "")
|
|
||||||
local sz = tO(s:sub(125, 135))
|
|
||||||
if tFN:sub(1, 5) ~= "code/" then
|
|
||||||
tW = math.ceil(sz / 512)
|
|
||||||
else
|
|
||||||
tFN = tFN:sub(6)
|
|
||||||
if tFN == "" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if tFN:sub(#tFN) == "/" then
|
|
||||||
tW = math.ceil(sz / 512)
|
|
||||||
D.makeDirectory(tFN)
|
|
||||||
else
|
|
||||||
tF = D.open(tFN, "wb")
|
|
||||||
tFSR = sz
|
|
||||||
if tFSR == 0 then
|
|
||||||
D.close(tF)
|
|
||||||
tF = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sN, sC = 0, 0
|
|
||||||
|
|
||||||
function sector(n)
|
|
||||||
tA(n)
|
|
||||||
sN = sN + 1
|
|
||||||
if G then
|
|
||||||
local a = sN / sC
|
|
||||||
G.fill(1, 2, 50, 1, " ")
|
|
||||||
G.set(2, 2, "KittenOS NEO Installer : " .. tFN)
|
|
||||||
G.setForeground(0xFFFFFF)
|
|
||||||
G.setBackground(0x000000)
|
|
||||||
G.fill(2, 4, 48, 1, " ")
|
|
||||||
G.setBackground(0xFFFFFF)
|
|
||||||
G.setForeground(0x000000)
|
|
||||||
G.fill(2, 4, math.ceil(48 * a), 1, " ")
|
|
||||||
end
|
|
||||||
if sN % 8 == 0 then
|
|
||||||
O.pullSignal(0.05)
|
|
||||||
end
|
|
||||||
if sN == sC then
|
|
||||||
dieCB()
|
|
||||||
O.shutdown(true)
|
|
||||||
end
|
|
||||||
end
|
|
17
laboratory/client.cfg
Normal file
17
laboratory/client.cfg
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
["components"]={
|
||||||
|
{"screen","67c66973-51ff-4aec-29cd-baabf2fbe346",},
|
||||||
|
{"gpu","9b7fe47d-77d0-1623-0dc5-126752e3f2c7",44800,},
|
||||||
|
{"eeprom","94a9cc26-347e-cc46-7faf-0c131bb7d8b7",4096,256,"EEPROM",},
|
||||||
|
{"computer","36bc34ad-8c4a-d19a-10e3-0162c6f3295a",1.04858e+06,},
|
||||||
|
{"filesystem","tmpfs",true,"tmpfs",},
|
||||||
|
{"filesystem","c1-sda",},
|
||||||
|
{"filesystem","c1-sdb",},
|
||||||
|
{"keyboard","dd142450-613c-435d-6049-743b27434cc1","67c66973-51ff-4aec-29cd-baabf2fbe346",},
|
||||||
|
{"modem","460ae893-9aa9-f10d-6bb0-462199da7376",56000,8192,8,},
|
||||||
|
{"internet","ef97c750-d30a-ad33-5321-6e7a64ba3baa",true,true,},
|
||||||
|
{"data","c5243e5f-cd2f-6c39-dfb2-5a788dcdef7c",["tier"]=1,},
|
||||||
|
{"sandbox","ece7b9ba-1625-f3f6-d74d-6e641a5de07f",},
|
||||||
|
},
|
||||||
|
["system"]={["allowBytecode"]=false,["allowGC"]=false,["maxTcpConnections"]=4,["timeout"]=math.huge,},
|
||||||
|
}
|
10
laboratory/locvm.sh
Executable file
10
laboratory/locvm.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
# THIS SOFTWARE.
|
||||||
|
|
||||||
|
ocvm .
|
@ -1,140 +0,0 @@
|
|||||||
--OCEmu configuration. Designed to mimic HOCON syntax, but is not exactly HOCON
|
|
||||||
--syntax.
|
|
||||||
ocemu {
|
|
||||||
|
|
||||||
--Client side settings, presentation and performance related stuff.
|
|
||||||
client {
|
|
||||||
|
|
||||||
--The sample rate used for generating beeps of computers' internal speakers.
|
|
||||||
--Use custom values at your own responsibility here; if it breaks OC you'll
|
|
||||||
--get no support. Some potentially reasonable lower values are 16000 or even
|
|
||||||
--8000 (which was the old default, but leads to artifacting on certain
|
|
||||||
--frequencies).
|
|
||||||
beepSampleRate=44100
|
|
||||||
|
|
||||||
--The base volume of beeps generated by computers. This may be in a range of
|
|
||||||
--[0, 127], where 0 means mute (the sound will not even be generated), and
|
|
||||||
--127 means maximum amplitude / volume.
|
|
||||||
beepVolume=32
|
|
||||||
|
|
||||||
--The color of monochrome text (i.e. displayed when in 1-bit color depth,
|
|
||||||
--e.g. tier one screens / GPUs, or higher tier set to 1-bit color depth).
|
|
||||||
--Defaults to white, feel free to make it some other color, tho!
|
|
||||||
monochromeColor="0xFFFFFF"
|
|
||||||
}
|
|
||||||
|
|
||||||
--Computer related settings, concerns server performance and security.
|
|
||||||
computer {
|
|
||||||
|
|
||||||
--The maximum size of the byte array that can be stored on EEPROMs as
|
|
||||||
--configuration data.
|
|
||||||
eepromDataSize=256
|
|
||||||
|
|
||||||
--The maximum size of the byte array that can be stored on EEPROMs as
|
|
||||||
--executable data..
|
|
||||||
eepromSize=4096
|
|
||||||
|
|
||||||
--Settings specific to the Lua architecture.
|
|
||||||
lua {
|
|
||||||
|
|
||||||
--Whether to allow loading precompiled bytecode via Lua's `load` function,
|
|
||||||
--or related functions (`loadfile`, `dofile`). Enable this only if you
|
|
||||||
--absolutely trust all users on your server and all Lua code you run. This
|
|
||||||
--can be a MASSIVE SECURITY RISK, since precompiled code can easily be
|
|
||||||
--used for exploits, running arbitrary code on the real server! I cannot
|
|
||||||
--stress this enough: only enable this is you know what you're doing.
|
|
||||||
allowBytecode=false
|
|
||||||
|
|
||||||
--Whether to allow user defined __gc callbacks, i.e. __gc callbacks
|
|
||||||
--defined *inside* the sandbox. Since garbage collection callbacks are not
|
|
||||||
--sandboxed (hooks are disabled while they run), this is not recommended.
|
|
||||||
allowGC=false
|
|
||||||
}
|
|
||||||
|
|
||||||
--The time in seconds a program may run without yielding before it is
|
|
||||||
--forcibly aborted. This is used to avoid stupidly written or malicious
|
|
||||||
--programs blocking other computers by locking down the executor threads.
|
|
||||||
--Note that changing this won't have any effect on computers that are
|
|
||||||
--already running - they'll have to be rebooted for this to take effect.
|
|
||||||
timeout=5
|
|
||||||
}
|
|
||||||
|
|
||||||
--Emulator related settings. Components, accuracy, and debugging.
|
|
||||||
emulator {
|
|
||||||
|
|
||||||
--Default components available to the computer.
|
|
||||||
components {
|
|
||||||
|
|
||||||
{"gpu", "c1-gpu-tier3", 0, 160, 50, 3},
|
|
||||||
{"gpu", "c1-gpu-tier1", 0, 50, 16, 1},
|
|
||||||
{"screen_sdl2", "c1-screen-tier3", -1, 160, 50, 3},
|
|
||||||
{"screen_sdl2", "c1-screen-tier1", -1, 50, 16, 1},
|
|
||||||
{"modem", "c1-modem", 1, false},
|
|
||||||
{"eeprom", "c1-eeprom", 9, "lua/bios.lua"},
|
|
||||||
{"filesystem", "c1-tmpfs", -1, "tmpfs", "tmpfs", false, 5},
|
|
||||||
{"filesystem", "c1-sda", 5, nil, "Workbench", false, 4},
|
|
||||||
{"filesystem", "c1-sdb", 5, nil, "Repository", false, 4},
|
|
||||||
{"filesystem", "openos", 0, "loot/openos", "openos", true, 1},
|
|
||||||
{"internet", "c1-internet", 2},
|
|
||||||
{"computer", "c1-computer", -1},
|
|
||||||
{"ocemu", "c1-ocemu", -1},
|
|
||||||
{"keyboard_sdl2", "c1-keyboard", -1}
|
|
||||||
}
|
|
||||||
|
|
||||||
--Whether to enable the emulator's extremely verbose logging.
|
|
||||||
debug=false
|
|
||||||
|
|
||||||
--Whether to choose performance over timing-accuracy.
|
|
||||||
fast=false
|
|
||||||
|
|
||||||
--Whether to return vague error messages like OpenComputers.
|
|
||||||
vague=false
|
|
||||||
}
|
|
||||||
|
|
||||||
filesystem {
|
|
||||||
|
|
||||||
--The maximum block size that can be read in one 'read' call on a file
|
|
||||||
--system. This is used to limit the amount of memory a call from a user
|
|
||||||
--program can cause to be allocated on the host side: when 'read' is, called
|
|
||||||
--a byte array with the specified size has to be allocated. So if this
|
|
||||||
--weren't limited, a Lua program could trigger massive memory allocations
|
|
||||||
--regardless of the amount of RAM installed in the computer it runs on. As a
|
|
||||||
--side effect this pretty much determines the read performance of file
|
|
||||||
--systems.
|
|
||||||
maxReadBuffer=2048
|
|
||||||
}
|
|
||||||
|
|
||||||
internet {
|
|
||||||
|
|
||||||
--Whether to allow HTTP requests via internet cards. When enabled, the
|
|
||||||
--`request` method on internet card components becomes available.
|
|
||||||
enableHttp=true
|
|
||||||
|
|
||||||
--Whether to allow TCP connections via internet cards. When enabled, the
|
|
||||||
--`connect` method on internet card components becomes available.
|
|
||||||
enableTcp=true
|
|
||||||
}
|
|
||||||
|
|
||||||
--Other settings that you might find useful to tweak.
|
|
||||||
misc {
|
|
||||||
|
|
||||||
--The maximum size of network packets to allow sending via network cards.
|
|
||||||
--This has *nothing to do* with real network traffic, it's just a limit for
|
|
||||||
--the network cards, mostly to reduce the chance of computer with a lot of
|
|
||||||
--RAM killing those with less by sending huge packets. This does not apply
|
|
||||||
--to HTTP traffic.
|
|
||||||
maxNetworkPacketSize=8192
|
|
||||||
|
|
||||||
--The maximum distance a wireless message can be sent. In other words, this
|
|
||||||
--is the maximum signal strength a wireless network card supports. This is
|
|
||||||
--used to limit the search range in which to check for modems, which may or
|
|
||||||
--may not lead to performance issues for ridiculous ranges - like, you know,
|
|
||||||
--more than the loaded area. See also: `wirelessCostPerRange`.
|
|
||||||
maxWirelessRange=400
|
|
||||||
}
|
|
||||||
|
|
||||||
--The configuration version this config was generated at. This is used to
|
|
||||||
--allow the emulator to reset/migrate parts of the config when their meaning
|
|
||||||
--has changed across versions.
|
|
||||||
version=3
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ ocemu {
|
|||||||
{"gpu", "c1-gpu-tier3", 0, 160, 50, 3},
|
{"gpu", "c1-gpu-tier3", 0, 160, 50, 3},
|
||||||
{"gpu", "c1-gpu-tier1", 0, 50, 16, 1},
|
{"gpu", "c1-gpu-tier1", 0, 50, 16, 1},
|
||||||
{"screen_sdl2", "c1-screen-tier3", -1, 160, 50, 3},
|
{"screen_sdl2", "c1-screen-tier3", -1, 160, 50, 3},
|
||||||
{"screen_sdl2", "c1-screen-tier1", -1, 50, 16, 1},
|
-- {"screen_sdl2", "c1-screen-tier1", -1, 50, 16, 1},
|
||||||
{"modem", "c1-modem", 1, false},
|
{"modem", "c1-modem", 1, false},
|
||||||
{"eeprom", "c1-eeprom", 9, "lua/bios.lua"},
|
{"eeprom", "c1-eeprom", 9, "lua/bios.lua"},
|
||||||
{"filesystem", "c1-tmpfs", -1, "tmpfs", "tmpfs", false, 5},
|
{"filesystem", "c1-tmpfs", -1, "tmpfs", "tmpfs", false, 5},
|
||||||
|
11
laboratory/reset-i.sh
Executable file
11
laboratory/reset-i.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This is released into the public domain.
|
||||||
|
# No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
|
cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb tmpfs
|
||||||
|
mkdir c1-sda c1-sdb
|
||||||
|
echo -n c1-sda > c1-eeprom/data.bin
|
||||||
|
cd ..
|
||||||
|
./package.sh $*
|
||||||
|
cp inst.lua laboratory/c1-sda/init.lua
|
@ -3,11 +3,8 @@
|
|||||||
# This is released into the public domain.
|
# This is released into the public domain.
|
||||||
# No warranty is provided, implied or otherwise.
|
# No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb tmpfs
|
cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb
|
||||||
mkdir c1-sda c1-sdb
|
mkdir c1-sda c1-sdb
|
||||||
echo -n c1-sda > c1-eeprom/data.bin
|
echo -n c1-sda > c1-eeprom/data.bin
|
||||||
cd ..
|
|
||||||
cp -r code/* laboratory/c1-sdb/
|
./update.sh
|
||||||
cp -r repository/* laboratory/c1-sdb/
|
|
||||||
lua clawmerge.lua repository/data/app-claw/local.lua code/data/app-claw/local.lua > laboratory/c1-sdb/data/app-claw/local.lua
|
|
||||||
cp -r laboratory/c1-sdb/* laboratory/c1-sda/
|
|
||||||
|
11
laboratory/update.sh
Executable file
11
laboratory/update.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This is released into the public domain.
|
||||||
|
# No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
cp -r code/* laboratory/c1-sdb/
|
||||||
|
cp -r repository/* laboratory/c1-sdb/
|
||||||
|
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/code-claw.lua > /dev/null
|
||||||
|
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/repo-claw.lua >> /dev/null
|
||||||
|
cp -r laboratory/c1-sdb/* laboratory/c1-sda/
|
28
mkucinst.lua
28
mkucinst.lua
@ -1,28 +0,0 @@
|
|||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
os.execute("tar -cf code.tar code")
|
|
||||||
os.execute("cat insthead.lua > inst.lua")
|
|
||||||
local f = io.open("inst.lua", "ab")
|
|
||||||
|
|
||||||
local df = io.open("code.tar", "rb")
|
|
||||||
local sc = 0
|
|
||||||
while true do
|
|
||||||
local d = df:read(512)
|
|
||||||
if not d then break end
|
|
||||||
sc = sc + 1
|
|
||||||
end
|
|
||||||
df:close()
|
|
||||||
local df = io.open("code.tar", "rb")
|
|
||||||
f:write("dieCB = function () end")
|
|
||||||
f:write("sC = " .. sc .. "\n")
|
|
||||||
while true do
|
|
||||||
local d = df:read(512)
|
|
||||||
if d then
|
|
||||||
f:write(string.format("sector(%q)", d))
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
df:close()
|
|
||||||
f:close()
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This is released into the public domain.
|
|
||||||
# No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
stat repobuild/data/app-claw/local.lua && rm -rf repobuild
|
|
||||||
mkdir repobuild
|
|
||||||
cp -r code/* repobuild/
|
|
||||||
cp -r repository/* repobuild/
|
|
||||||
cp inst-gold.lua repobuild/inst.lua
|
|
||||||
lua clawmerge.lua repository/data/app-claw/local.lua code/data/app-claw/local.lua > repobuild/data/app-claw/local.lua
|
|
11
package-rel.sh
Executable file
11
package-rel.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
# THIS SOFTWARE.
|
||||||
|
|
||||||
|
./package.sh bdvlite deflate
|
||||||
|
|
21
package-repo.sh
Executable file
21
package-repo.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
# THIS SOFTWARE.
|
||||||
|
|
||||||
|
# Package repository using supplied inst.lua (use inst-gold.lua for repository branch)
|
||||||
|
|
||||||
|
# this is a guard check to avoid removing repobuild if it's blatantly
|
||||||
|
# not the actual repobuild directory (this is an rm -rf after all)
|
||||||
|
stat repobuild/data/app-claw 1>/dev/null 2>/dev/null && rm -rf repobuild
|
||||||
|
|
||||||
|
mkdir -p repobuild
|
||||||
|
cp -r code/* repobuild/
|
||||||
|
cp -r repository/* repobuild/
|
||||||
|
cp $1 repobuild/inst.lua
|
||||||
|
lua claw/clawconv.lua repobuild/data/app-claw/ < claw/code-claw.lua > repobuild/data/app-claw/local.c2l
|
||||||
|
lua claw/clawconv.lua repobuild/data/app-claw/ < claw/repo-claw.lua >> repobuild/data/app-claw/local.c2l
|
33
package.sh
33
package.sh
@ -1,20 +1,27 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# This is released into the public domain.
|
# Copyright (C) 2018-2021 by KittenOS NEO contributors
|
||||||
# No warranty is provided, implied or otherwise.
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
# THIS SOFTWARE.
|
||||||
|
|
||||||
|
rm code/data/app-claw/*
|
||||||
|
mkdir -p code/data/app-claw
|
||||||
|
lua claw/clawconv.lua code/data/app-claw/ < claw/code-claw.lua > /dev/null
|
||||||
rm code.tar
|
rm code.tar
|
||||||
# Hey, look behind you, there's nothing to see here.
|
# Hey, look behind you, there's nothing to see here.
|
||||||
# ... ok, are they seriously all named "Mann"?
|
# ... ok, are they seriously all named "Mann"?
|
||||||
tar --owner=gray:0 --group=mann:0 -cf code.tar code
|
cd code
|
||||||
lua heroes.lua `wc -c code.tar` | lua bonecrunch.lua > inst.lua
|
tar --mtime=0 --owner=gray:0 --group=mann:0 -cf ../code.tar .
|
||||||
echo -n "--[[" >> inst.lua
|
cd ..
|
||||||
cat com2/code.tar.bd >> inst.lua
|
|
||||||
echo -n "]]" >> inst.lua
|
|
||||||
|
|
||||||
stat repobuild/data/app-claw/local.lua && rm -rf repobuild
|
# The Installer Creator
|
||||||
mkdir repobuild
|
cd inst
|
||||||
cp -r code/* repobuild/
|
lua build.lua `git status --porcelain=2 --branch | grep branch.oid | grep -E -o "[0-9a-f]*$" -` ../code.tar $* > ../inst.lua
|
||||||
cp -r repository/* repobuild/
|
lua status.lua ../inst.lua
|
||||||
cp inst.lua repobuild/
|
cd ..
|
||||||
lua clawmerge.lua repository/data/app-claw/local.lua code/data/app-claw/local.lua > repobuild/data/app-claw/local.lua
|
|
||||||
|
# Common Repository Setup Code
|
||||||
|
./package-repo.sh inst.lua
|
||||||
|
@ -1,609 +0,0 @@
|
|||||||
-- KOSNEO inst.
|
|
||||||
-- This is released into the public domain.
|
|
||||||
-- No warranty is provided, implied or otherwise.
|
|
||||||
|
|
||||||
-- PADPADPADPADPADPADPADPAD
|
|
||||||
|
|
||||||
local C, O, G, D = component, computer
|
|
||||||
local sAddr = C.list("screen", true)()
|
|
||||||
if sAddr then
|
|
||||||
G = C.list("gpu", true)()
|
|
||||||
if G then
|
|
||||||
G = C.proxy(G)
|
|
||||||
G.bind(sAddr)
|
|
||||||
G.setForeground(0xFFFFFF)
|
|
||||||
G.setBackground(0x000000)
|
|
||||||
G.setResolution(50, 5)
|
|
||||||
G.setDepth(1)
|
|
||||||
G.fill(1, 1, 50, 5, " ")
|
|
||||||
G.setBackground(0xFFFFFF)
|
|
||||||
G.setForeground(0x000000)
|
|
||||||
G.fill(1, 2, 50, 1, " ")
|
|
||||||
G.set(2, 2, "KittenOS NEO Installer")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
D = C.proxy(O.getBootAddress())
|
|
||||||
|
|
||||||
local file = nil
|
|
||||||
local fileName = "Starting..."
|
|
||||||
local fileSizeRm = 0
|
|
||||||
local ws = 0
|
|
||||||
|
|
||||||
local convoct
|
|
||||||
convoct = function (oct)
|
|
||||||
local v = oct:byte(#oct) - 0x30
|
|
||||||
if #oct > 1 then
|
|
||||||
return (convoct(oct:sub(1, #oct - 1)) * 8) + v
|
|
||||||
end
|
|
||||||
return v
|
|
||||||
end
|
|
||||||
local function sectorCore(sector)
|
|
||||||
if ws > 0 then
|
|
||||||
ws = ws - 1
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if file then
|
|
||||||
local takeaway = math.min(512, fileSizeRm)
|
|
||||||
D.write(file, sector:sub(1, takeaway))
|
|
||||||
fileSizeRm = fileSizeRm - takeaway
|
|
||||||
if fileSizeRm == 0 then
|
|
||||||
D.close(file)
|
|
||||||
file = nil
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local name = sector:sub(1, 100):gsub("\x00", "")
|
|
||||||
local sz = convoct(sector:sub(125, 135))
|
|
||||||
if name:sub(1, 5) ~= "code/" then
|
|
||||||
ws = math.ceil(sz / 512)
|
|
||||||
else
|
|
||||||
if name:sub(#name, #name) == "/" then
|
|
||||||
ws = math.ceil(sz / 512)
|
|
||||||
D.makeDirectory(name:sub(6))
|
|
||||||
else
|
|
||||||
fileName = name:sub(6)
|
|
||||||
file = D.open(fileName, "wb")
|
|
||||||
fileSizeRm = sz
|
|
||||||
if file then
|
|
||||||
if fileSizeRm == 0 then
|
|
||||||
D.close(file)
|
|
||||||
file = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local dieCB = function () end
|
|
||||||
|
|
||||||
local sectorNum = 0
|
|
||||||
local sectorCount = 0
|
|
||||||
|
|
||||||
local function sector(n)
|
|
||||||
sectorCore(n)
|
|
||||||
sectorNum = sectorNum + 1
|
|
||||||
if G then
|
|
||||||
local a = sectorNum / sectorCount
|
|
||||||
G.fill(1, 2, 50, 1, " ")
|
|
||||||
G.set(2, 2, "KittenOS NEO Installer : " .. fileName)
|
|
||||||
G.setForeground(0xFFFFFF)
|
|
||||||
G.setBackground(0x000000)
|
|
||||||
G.fill(2, 4, 48, 1, " ")
|
|
||||||
G.setBackground(0xFFFFFF)
|
|
||||||
G.setForeground(0x000000)
|
|
||||||
G.fill(2, 4, math.ceil(48 * a), 1, " ")
|
|
||||||
end
|
|
||||||
if sectorNum % 8 == 0 then
|
|
||||||
O.pullSignal(0.05)
|
|
||||||
end
|
|
||||||
if sectorNum == sectorCount then
|
|
||||||
dieCB()
|
|
||||||
O.shutdown(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sectorCount = 260
|
|
||||||
D.remove("init-symsear.lua")
|
|
||||||
D.rename("init.lua", "init-symsear.lua")
|
|
||||||
local instHandle = D.open("init-symsear.lua", "rb")
|
|
||||||
dieCB = function ()
|
|
||||||
D.close(instHandle)
|
|
||||||
D.remove("init-symsear.lua")
|
|
||||||
end
|
|
||||||
local syms = {" ","s","e","t","a","i","\24","(","r",".","\
|
|
||||||
","p","\"","o","c","m",", ","\1","l","n",")","d","u","\17","\9","x","-","\7","\6","\8","\4","\13","\2","\3","\5","g","\14","\21","\11"," then\
|
|
||||||
","1","w"," ","\12","\18","\22","f","F","y",",","\20","re","b","k"," = ","\23","return "," local ","\16","v"," if ","\
|
|
||||||
","\15","\19","\
|
|
||||||
"," ","[","en","/","0","]","path","nction (","\
|
|
||||||
","se","h"," =","or","S","T","le","\
|
|
||||||
local ",")\
|
|
||||||
","= fu","on"," == ","ne",")\
|
|
||||||
","functio","\
|
|
||||||
end\
|
|
||||||
","D","{"," t","n ","oc","lo"," end\
|
|
||||||
","\0\0\0\0\0\0\0\0\0","un"," i","W","\0\0\0\0\0\0","fu","et"," end\
|
|
||||||
","then ","nd","ni","A","ing"," tab","loca","etting",")\
|
|
||||||
","ct","C","P","}","\
|
|
||||||
end\
|
|
||||||
",")\
|
|
||||||
","onit","= ","end\
|
|
||||||
","\0","I","Y"," do\
|
|
||||||
","return\
|
|
||||||
","le.inser"," = func","= \"","al"," r"," e","in","he","nc"," e","j","donkonit","tion ()",") do\
|
|
||||||
"," the","\
|
|
||||||
",")\
|
|
||||||
","ur","#","+","N","cursor",".inse",", v ","nction (w"," neo.req"," for "," then\
|
|
||||||
","\0\0\0\0\0\0\0","nd\
|
|
||||||
","()\
|
|
||||||
","neo.","ath","table","l ","do","2","3",":","H"," = nil\
|
|
||||||
","nd\
|
|
||||||
e","hen\
|
|
||||||
","\7local ","indowCore",")\
|
|
||||||
end\
|
|
||||||
","d\") end\
|
|
||||||
"," = false","if ","pairs(","dow","string\"","ti","O","uestAcces","nd\
|
|
||||||
if ","icode."," if","v in ","pkg, pid","000","750\0000001","end\
|
|
||||||
e","750\0000000"," else\
|
|
||||||
","window","end","00",".neo.sys.","neoux.tc","= {}\
|
|
||||||
","(window, ","5","=","E","R",") end\
|
|
||||||
"," cursor","request","ode/app"," return e","\" the","equire("," "," then",".neo.pub.","hile true"," end"," en","\0\0","B","M"," ret","for ","in ipai"," true\
|
|
||||||
","close","code.sub","error(\"","return t","oroutine"," end\
|
|
||||||
if","end\
|
|
||||||
en","tion ","\", funct",":sub(","vailable"," end\
|
|
||||||
"," l"," == \"","prima"," if type(","ryWindow","window.s"," end\
|
|
||||||
","L","X","~","on ("," in ipair"," for _, v"," for k","\0\0\0\0\0cod","lose()\
|
|
||||||
"," = funct","rror(\"Exp","nsurePath","s.primary","primary","buildingS","unic"," "," re","surfaces","disallowe","ackground","neoux.","ccess","selectUnk"," end\
|
|
||||||
"," = uni","\
|
|
||||||
end\
|
|
||||||
"," f","7","Z","z","for k","rue\
|
|
||||||
end\
|
|
||||||
","ode.len("," end\
|
|
||||||
","lse\
|
|
||||||
",") end","end\
|
|
||||||
"," fu",":sub(1, ","sub(1, 4)"," ","neo","the","if not "," th","tion","unknownA","end\
|
|
||||||
","[1] == \"","= unico","Acces","\
|
|
||||||
end\
|
|
||||||
\
|
|
||||||
l","n\
|
|
||||||
","\") end\
|
|
||||||
","de.len("," end","\" then\
|
|
||||||
","0\0000001","urface","nd\
|
|
||||||
","()\
|
|
||||||
","(surfaces"," if ","\0\0\0\0\0\0\0\0","unc","urn","\
|
|
||||||
"," end\
|
|
||||||
"," neoux","ction","\
|
|
||||||
end\
|
|
||||||
","\
|
|
||||||
","neoux","\24\0\0\0\0\0\0\0\0","\
|
|
||||||
end"," end\
|
|
||||||
end\
|
|
||||||
","\
|
|
||||||
end\
|
|
||||||
"," if "," err","s[1] == \"","unicode."," window"," if ","ocal fun","= false","\0\0\0\0\0\0\0000","\0\0\0\0\0\0\00000","code","_, v in i","()\
|
|
||||||
","d\
|
|
||||||
","f ev == \""," return",", bg, fg"," end"," neoux.","\0\0\0","w.close(","\
|
|
||||||
if ev"," i"," if not ","if kc == ",")\
|
|
||||||
end\
|
|
||||||
","indow","onkonit","00175","table.",", bg, fg)"," l"," end\
|
|
||||||
",") == \"","d\
|
|
||||||
"," return ","rn","ca","q"," tabl"," error(\"","end\
|
|
||||||
re"," in ","hen err","nd\
|
|
||||||
en","nd\
|
|
||||||
","\
|
|
||||||
end","turn ","x.neo.","ion ("," table","false","string","e.len(","d\
|
|
||||||
"," re","1, unicod","cursorX ","local ","end\
|
|
||||||
end\
|
|
||||||
","cal","\" then e","nd\
|
|
||||||
if k","ion","00644\00000"," end\
|
|
||||||
","\
|
|
||||||
end"," window."," e","if not","== \"",", func"," neo.",", functi","\
|
|
||||||
end\
|
|
||||||
end"," r","end\
|
|
||||||
","ion (w)\
|
|
||||||
","\
|
|
||||||
end"," = false\
|
|
||||||
"," ret","tu"," end\
|
|
||||||
","f ","unction","= nil\
|
|
||||||
","th","n\
|
|
||||||
","6","U","_","requir","eturn\
|
|
||||||
"," funct","eturn tr","\
|
|
||||||
\
|
|
||||||
local"," table.","eques","rn ",")\
|
|
||||||
r",".insert(","ode.",")\
|
|
||||||
end","== ","\0\0\0\0\0\0\0c","n\
|
|
||||||
","\0\0\0\0\0","()\
|
|
||||||
"," = nil","able.","n\
|
|
||||||
"," = n","return","000644\0000","Access","able","etu","d\
|
|
||||||
","\
|
|
||||||
if ","end\
|
|
||||||
end","nction (p","ub(1, 4) "," return "," return","lse\
|
|
||||||
","abl","= uni","for k, ","\0\0\0\0\0\0\0\0c","cursorY","ble","bg, fg)\
|
|
||||||
","\
|
|
||||||
e","ind","ret","tring\"","000000"," neo","pairs","then\
|
|
||||||
",")\
|
|
||||||
","le.inse","loc","\
|
|
||||||
end","n error","\
|
|
||||||
end\
|
|
||||||
\
|
|
||||||
","if s[1] =","lse\
|
|
||||||
","turn","ursor","function","neou","\0\0\0\0\0\0c","function ","\0000001","end\
|
|
||||||
e","eo.","Access(\""," re"," lo","\
|
|
||||||
e",")\
|
|
||||||
end","urn ","\
|
|
||||||
re"," end\
|
|
||||||
e"," = f","\0\0\0\0","cal ","\0000000644\0","in ip","\
|
|
||||||
en"," return",")\
|
|
||||||
i","ction ","\
|
|
||||||
end\
|
|
||||||
","ode","equire(\"","r(\"Expect","ctio"," cursorY","if","%","4","<","G","\
|
|
||||||
local f","\
|
|
||||||
ret"," for ","d\
|
|
||||||
if"," erro","true\
|
|
||||||
end","ed\") end","hen ","nd\
|
|
||||||
en","al ","on ","] then\
|
|
||||||
","string\")","for _, ","unicode.l","[1] == ","true\
|
|
||||||
","uestAc","nd\
|
|
||||||
end\
|
|
||||||
"," for k, "," if ev ","then\
|
|
||||||
","\
|
|
||||||
en",")\
|
|
||||||
en","do\
|
|
||||||
","e.ins",".primary"," true","coroutine","return\
|
|
||||||
","airs(",") end\
|
|
||||||
","nd\
|
|
||||||
end\
|
|
||||||
\
|
|
||||||
","\
|
|
||||||
return","window, ","end\
|
|
||||||
e","end\
|
|
||||||
end","750\0000","eturn t",", functio"," e","d\") end","en\
|
|
||||||
","ocal","icode.len","e\
|
|
||||||
","n\
|
|
||||||
","w.close()"," uni","sub(","n ipairs("," for ","end\
|
|
||||||
","ion ()","end\
|
|
||||||
en","quest","cursorY ","eturn","unicode.s","x.neo.pub"," = neo","hen\
|
|
||||||
","then\
|
|
||||||
","string\") ","in ipa"," retur","indowCor"," re","750\00000"," do\
|
|
||||||
",")\
|
|
||||||
if "," then ret","\") end"," en","n\
|
|
||||||
","ipairs"," then err","d\
|
|
||||||
en","= f"," local",".neo.","\24\0\0\0\0\0\0\0","func","()\
|
|
||||||
",")\
|
|
||||||
en","curs","\
|
|
||||||
loca","ode/apps","nd\
|
|
||||||
if "," i"," = neo.r","kg, pid, ","\
|
|
||||||
i","win","code.sub(","require","wind"," else\
|
|
||||||
","close()"," end\
|
|
||||||
e","\
|
|
||||||
\
|
|
||||||
local "," then re","\
|
|
||||||
e",".request","wnAvailab","tion (","\
|
|
||||||
local ","error(","\0000001750\0","n\
|
|
||||||
","d\
|
|
||||||
"," ","uestA","reques","end\
|
|
||||||
end\
|
|
||||||
\
|
|
||||||
","ion ()\
|
|
||||||
"," curso","then\
|
|
||||||
","0001750","surfac",".close("," function","= neo.","if type("," loc","d\
|
|
||||||
e","oroutine."," do\
|
|
||||||
"," else\
|
|
||||||
","tion ()\
|
|
||||||
",", v in ","window.","neo.re","0000","\000000","\
|
|
||||||
end\
|
|
||||||
","ipairs("," ret","\"x.neo.pu","error","\
|
|
||||||
i","\
|
|
||||||
end","()\
|
|
||||||
","= nil\
|
|
||||||
","nsert(","n erro","rror(\"","nil\
|
|
||||||
","cursorX ="," do\
|
|
||||||
"," for","turn f","en\
|
|
||||||
"," table.","\
|
|
||||||
","\") end\
|
|
||||||
","\") end\
|
|
||||||
",".close()\
|
|
||||||
","\
|
|
||||||
re","d\
|
|
||||||
e","\
|
|
||||||
end\
|
|
||||||
","ownAvaila","000644\00000"," false\
|
|
||||||
","\
|
|
||||||
re","false\
|
|
||||||
","ion ()\
|
|
||||||
",")\
|
|
||||||
e","urn end\
|
|
||||||
",")\
|
|
||||||
if","x.neo.sys","indow, ","then\
|
|
||||||
",")\
|
|
||||||
if t","cti","ion ","ion (w","\" then"," = nil\
|
|
||||||
","then","e\" then\
|
|
||||||
"," if","on (w)\
|
|
||||||
",") do\
|
|
||||||
"," en","tAccess(\"","surePath"," end\
|
|
||||||
end","\
|
|
||||||
end\
|
|
||||||
","e.inse"," table.i"," local","oca","n (","0 then\
|
|
||||||
",") end\
|
|
||||||
"," loc","se\
|
|
||||||
","do\
|
|
||||||
","nd\
|
|
||||||
end\
|
|
||||||
"," then e","0000644\0","ion ()\
|
|
||||||
","ocal ","end\
|
|
||||||
if ","e\
|
|
||||||
"," then\
|
|
||||||
"," local","icode.le","\" then "," ==","] == \"","eoux","ndow","\0\0\0\0\0c","nownAvail"," functi","0\000000000","eoux.tc","hen error"," = neo.","table.ins"," window","(window","d\
|
|
||||||
if ","\
|
|
||||||
if ","\
|
|
||||||
local","end\
|
|
||||||
e","nd\
|
|
||||||
end","insert("," local ","k, v i","surface","eturn ","\
|
|
||||||
loc","sub(1, ","end\
|
|
||||||
if ","io","!","$","&","'","*","8","9",";",">","?","@","J","K","Q","V","\\","^","|","<22>","…","ˆ","‰","Œ","<22>","Ž","<22>","<22>","’","“","”","˜","¦","¬","¼","½","Â","ï",}
|
|
||||||
local bytBuf = ""
|
|
||||||
local bitBuf = ""
|
|
||||||
local function getByte()
|
|
||||||
if bytBuf == "" then
|
|
||||||
bytBuf = D.read(instHandle, 64)
|
|
||||||
end
|
|
||||||
local r = bytBuf:byte()
|
|
||||||
bytBuf = bytBuf:sub(2)
|
|
||||||
return r
|
|
||||||
end
|
|
||||||
while true do
|
|
||||||
if getByte() == 0 then break end
|
|
||||||
end
|
|
||||||
local function pb(c, p) if c % (p * 2) ~= c % p then bitBuf = bitBuf .. "1" else bitBuf = bitBuf .. "0" end end
|
|
||||||
local stn = 0
|
|
||||||
local function getBit()
|
|
||||||
if bitBuf == "" then
|
|
||||||
local c = getByte()
|
|
||||||
c = (c - stn) % 256 stn = stn + 3
|
|
||||||
pb(c, 1)
|
|
||||||
pb(c, 2)
|
|
||||||
pb(c, 4)
|
|
||||||
pb(c, 8)
|
|
||||||
pb(c, 16)
|
|
||||||
pb(c, 32)
|
|
||||||
pb(c, 64)
|
|
||||||
pb(c, 128)
|
|
||||||
end
|
|
||||||
local bit = bitBuf:sub(1, 1) == "1"
|
|
||||||
bitBuf = bitBuf:sub(2)
|
|
||||||
return bit
|
|
||||||
end
|
|
||||||
local buf = ""
|
|
||||||
local mode = false
|
|
||||||
local bc2 = 10
|
|
||||||
while true do
|
|
||||||
local bc = getBit()
|
|
||||||
local v = 0
|
|
||||||
if bc then bc = bc2 v = 64 else bc = 6 end
|
|
||||||
for bit = 0, bc - 1 do
|
|
||||||
if getBit() then v = v + (2 ^ bit) end
|
|
||||||
end
|
|
||||||
buf = buf .. syms[v]
|
|
||||||
if mode then
|
|
||||||
while #buf >= 512 do
|
|
||||||
sector(buf:sub(1, 512))
|
|
||||||
buf = buf:sub(513)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if #buf == 27939 then
|
|
||||||
stn = 0
|
|
||||||
bc2 = 11
|
|
||||||
bitBuf = ""
|
|
||||||
syms = {}
|
|
||||||
while #buf > 0 do
|
|
||||||
local len = buf:byte()
|
|
||||||
if len > 127 then error("symlen") end
|
|
||||||
buf = buf:sub(2)
|
|
||||||
local ch = buf:sub(1, len)
|
|
||||||
buf = buf:sub(len + 1)
|
|
||||||
table.insert(syms, ch)
|
|
||||||
end
|
|
||||||
mode = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--[[ |