Page MenuHomeFreeBSD

D14295.id39150.diff
No OneTemporary

D14295.id39150.diff

Index: stand/Makefile
===================================================================
--- stand/Makefile
+++ stand/Makefile
@@ -10,6 +10,7 @@
.endif
.if ${MK_LOADER_LUA} != "no"
SUBDIR+= liblua
+SUBDIR+= lua
.endif
SUBDIR+= man
Index: stand/lua/Makefile
===================================================================
--- /dev/null
+++ stand/lua/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+.include <bsd.init.mk>
+
+BINDIR= /boot/lua
+FILES= color.lua \
+ config.lua \
+ core.lua \
+ drawer.lua \
+ loader.lua \
+ menu.lua \
+ password.lua \
+ screen.lua
+
+.include <bsd.prog.mk>
Index: stand/lua/color.lua
===================================================================
--- /dev/null
+++ stand/lua/color.lua
@@ -0,0 +1,99 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local color = {};
+
+local core = require("core");
+
+color.BLACK = 0;
+color.RED = 1;
+color.GREEN = 2;
+color.YELLOW = 3;
+color.BLUE = 4;
+color.MAGENTA = 5;
+color.CYAN = 6;
+color.WHITE = 7;
+
+color.DEFAULT = 0;
+color.BRIGHT = 1;
+color.DIM = 2;
+
+function color.isEnabled()
+ local c = loader.getenv("loader_color");
+ if c ~= nil then
+ if c:lower() == "no" or c == "0" then
+ return false;
+ end
+ end
+ return not core.bootserial();
+end
+
+color.disabled = not color.isEnabled();
+
+
+function color.escapef(c)
+ if color.disabled then
+ return c;
+ end
+ return "\027[3"..c.."m";
+end
+
+function color.escapeb(c)
+ if color.disabled then
+ return c;
+ end
+ return "\027[4"..c.."m";
+end
+
+function color.escape(fg, bg, att)
+ if color.disabled then
+ return "";
+ end
+ if not att then
+ att = ""
+ else
+ att = att..";";
+ end
+ return "\027["..att.."3"..fg..";4"..bg.."m";
+end
+
+function color.default()
+ if color.disabled then
+ return "";
+ end
+ return "\027[0;37;40m";
+end
+
+function color.highlight(str)
+ if color.disabled then
+ return str;
+ end
+ return "\027[1m"..str.."\027[0m";
+end
+
+return color
Index: stand/lua/config.lua
===================================================================
--- /dev/null
+++ stand/lua/config.lua
@@ -0,0 +1,371 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local config = {};
+
+local modules = {};
+
+function config.setKey(k, n, v)
+ if modules[k] == nil then
+ modules[k] = {};
+ end
+ modules[k][n] = v;
+end
+
+local pattern_table = {
+ [1] = {
+ str = "^%s*(#.*)",
+ process = function(k, v) end
+ },
+ -- module_load="value"
+ [2] = {
+ str = "^%s*([%w_]+)_load%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if modules[k] == nil then
+ modules[k] = {};
+ end
+ modules[k].load = string.upper(v);
+ end
+ },
+ -- module_name="value"
+ [3] = {
+ str = "^%s*([%w_]+)_name%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "name", v);
+ end
+ },
+ -- module_type="value"
+ [4] = {
+ str = "^%s*([%w_]+)_type%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "type", v);
+ end
+ },
+ -- module_flags="value"
+ [5] = {
+ str = "^%s*([%w_]+)_flags%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "flags", v);
+ end
+ },
+ -- module_before="value"
+ [6] = {
+ str = "^%s*([%w_]+)_before%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "before", v);
+ end
+ },
+ -- module_after="value"
+ [7] = {
+ str = "^%s*([%w_]+)_after%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "after", v);
+ end
+ },
+ -- module_error="value"
+ [8] = {
+ str = "^%s*([%w_]+)_error%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "error", v);
+ end
+ },
+ -- exec="command"
+ [9] = {
+ str = "^%s*exec%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if loader.perform(k) ~= 0 then
+ print("Failed to exec '"..k.."'");
+ end
+ end
+ },
+ -- env_var="value"
+ [10] = {
+ str = "^%s*([%w%p]+)%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if loader.setenv(k, v) ~= 0 then
+ print("Failed to set '"..k.."' with value: "..v.."");
+ end
+ end
+ },
+ -- env_var=num
+ [11] = {
+ str = "^%s*([%w%p]+)%s*=%s*(%d+)%s*(.*)",
+ process = function(k, v)
+ if loader.setenv(k, v) ~= 0 then
+ print("Failed to set '"..k.."' with value: "..v.."");
+ end
+ end
+ }
+};
+
+function config.isValidComment(c)
+ if c ~= nil then
+ local s = string.match(c, "^%s*#.*");
+ if s == nil then
+ s = string.match(c, "^%s*$");
+ end
+ if s == nil then
+ return false;
+ end
+ end
+ return true;
+end
+
+function config.loadmod(mod, silent)
+ local status = true;
+ for k, v in pairs(mod) do
+ if v.load == "YES" then
+ local str = "load ";
+ if v.flags ~= nil then
+ str = str .. v.flags .. " ";
+ end
+ if v.type ~= nil then
+ str = str .. "-t " .. v.type .. " ";
+ end
+ if v.name ~= nil then
+ str = str .. v.name;
+ else
+ str = str .. k;
+ end
+
+ if v.before ~= nil then
+ if loader.perform(v.before) ~= 0 then
+ if not silent then
+ print("Failed to execute '"..v.before.."' before loading '"..k.."'");
+ end
+ status = false;
+ end
+ end
+
+ if loader.perform(str) ~= 0 then
+ if not silent then
+ print("Failed to execute '" .. str .. "'");
+ end
+ if v.error ~= nil then
+ loader.perform(v.error);
+ end
+ status = false;
+ end
+
+ if v.after ~= nil then
+ if loader.perform(v.after) ~= 0 then
+ if not silent then
+ print("Failed to execute '"..v.after.."' after loading '"..k.."'");
+ end
+ status = false;
+ end
+ end
+
+ else
+ --if not silent then print("Skiping module '".. k .. "'"); end
+ end
+ end
+
+ return status;
+end
+
+function config.parse(name, silent)
+ local f = io.open(name);
+ if f == nil then
+ if not silent then
+ print("Failed to open config: '" .. name.."'");
+ end
+ return false;
+ end
+
+ local text;
+ local r;
+
+ text, r = io.read(f);
+
+ if text == nil then
+ if not silent then
+ print("Failed to read config: '" .. name.."'");
+ end
+ return false;
+ end
+
+ local n = 1;
+ local status = true;
+
+ for line in string.gmatch(text, "([^\n]+)") do
+
+ if string.match(line, "^%s*$") == nil then
+ local found = false;
+
+ for i, val in ipairs(pattern_table) do
+ local k, v, c = string.match(line, val.str);
+ if k ~= nil then
+ found = true;
+
+ if config.isValidComment(c) then
+ val.process(k, v);
+ else
+ print("Malformed line ("..n.."):\n\t'"..line.."'");
+ status = false;
+ end
+
+ break;
+ end
+ end
+
+ if found == false then
+ print("Malformed line ("..n.."):\n\t'"..line.."'");
+ status = false;
+ end
+ end
+ n = n + 1;
+ end
+
+ return status;
+end
+
+function config.loadkernel()
+ local flags = loader.getenv("kernel_options") or "";
+ local kernel = loader.getenv("kernel");
+
+ local try_load = function (names)
+ for name in names:gmatch("([^;]+)%s*;?") do
+ r = loader.perform("load "..flags.." "..name);
+ if r == 0 then
+ return name;
+ end
+ end
+ return nil;
+ end;
+
+ local load_bootfile = function()
+ local bootfile = loader.getenv("bootfile");
+
+ -- append default kernel name
+ if not bootfile then
+ bootfile = "kernel";
+ else
+ bootfile = bootfile..";kernel";
+ end
+
+ return try_load(bootfile);
+ end;
+
+ -- kernel not set, try load from default module_path
+ if kernel == nil then
+ local res = load_bootfile();
+
+ if res ~= nil then
+ return true;
+ else
+ print("Failed to load kernel '"..res.."'");
+ return false;
+ end
+ else
+ local module_path = loader.getenv("module_path");
+ local res = nil;
+
+ -- first try load kernel with module_path = /boot/${kernel}
+ -- then try load with module_path=${kernel}
+ local paths = {"/boot/"..kernel, kernel};
+
+ for k,v in pairs(paths) do
+
+ loader.setenv("module_path", v);
+ res = load_bootfile();
+
+ -- succeeded add path to module_path
+ if res ~= nil then
+ loader.setenv("module_path", v..";"..module_path);
+ return true;
+ end
+ end
+
+ -- failed to load with ${kernel} as a directory
+ -- try as a file
+ res = try_load(kernel);
+ if res ~= nil then
+ return true;
+ else
+ print("Failed to load kernel '"..res.."'");
+ return false;
+ end
+ end
+end
+
+
+function config.load(file)
+
+ if not file then
+ file = "/boot/defaults/loader.conf";
+ end
+
+ if not config.parse(file) then
+-- print("Failed to parse configuration: '"..file.."'");
+ end
+
+ local f = loader.getenv("loader_conf_files");
+ if f ~= nil then
+ for name in string.gmatch(f, "([%w%p]+)%s*") do
+ if not config.parse(name) then
+-- print("Failed to parse configuration: '"..name.."'");
+ end
+ end
+ end
+
+ print("Loading kernel...");
+ config.loadkernel();
+
+ print("Loading configurations...");
+ if not config.loadmod(modules) then
+ print("Could not load configurations!");
+ end
+end
+
+function config.reload(kernel)
+ local res = 1;
+
+ -- unload all modules
+ print("Unloading modules...");
+ loader.perform("unload");
+
+ if kernel ~= nil then
+ res = loader.perform("load "..kernel);
+ if res == 0 then
+ print("Kernel '"..kernel.."' loaded!");
+ end
+ end
+
+ -- failed to load kernel or it is nil
+ -- then load default
+ if res == 1 then
+ print("Loading default kernel...");
+ config.loadkernel();
+ end
+
+ -- load modules
+ config.loadmod(modules);
+end
+
+return config
Index: stand/lua/core.lua
===================================================================
--- /dev/null
+++ stand/lua/core.lua
@@ -0,0 +1,154 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local core = {};
+
+function core.setVerbose(b)
+ if (b == nil) then
+ b = not core.verbose;
+ end
+
+ if (b == true) then
+ loader.setenv("boot_verbose", "YES");
+ else
+ loader.unsetenv("boot_verbose");
+ end
+ core.verbose = b;
+end
+
+function core.setSingleUser(b)
+ if (b == nil) then
+ b = not core.su;
+ end
+
+ if (b == true) then
+ loader.setenv("boot_single", "YES");
+ else
+ loader.unsetenv("boot_single");
+ end
+ core.su = b;
+end
+
+function core.setACPI(b)
+ if (b == nil) then
+ b = not core.acpi;
+ end
+
+ if (b == true) then
+ loader.setenv("acpi_load", "YES");
+ loader.setenv("hint.acpi.0.disabled", "0");
+ loader.unsetenv("loader.acpi_disabled_by_user");
+ else
+ loader.unsetenv("acpi_load");
+ loader.setenv("hint.acpi.0.disabled", "1");
+ loader.setenv("loader.acpi_disabled_by_user", "1");
+ end
+ core.acpi = b;
+end
+
+function core.setSafeMode(b)
+ if (b == nil) then
+ b = not core.sm;
+ end
+ if (b == true) then
+ loader.setenv("kern.smp.disabled", "1");
+ loader.setenv("hw.ata.ata_dma", "0");
+ loader.setenv("hw.ata.atapi_dma", "0");
+ loader.setenv("hw.ata.wc", "0");
+ loader.setenv("hw.eisa_slots", "0");
+ loader.setenv("kern.eventtimer.periodic", "1");
+ loader.setenv("kern.geom.part.check_integrity", "0");
+ else
+ loader.unsetenv("kern.smp.disabled");
+ loader.unsetenv("hw.ata.ata_dma");
+ loader.unsetenv("hw.ata.atapi_dma");
+ loader.unsetenv("hw.ata.wc");
+ loader.unsetenv("hw.eisa_slots");
+ loader.unsetenv("kern.eventtimer.periodic");
+ loader.unsetenv("kern.geom.part.check_integrity");
+ end
+ core.sm = b;
+end
+
+function core.kernelList()
+ local k = loader.getenv("kernel");
+ local v = loader.getenv("kernels") or "";
+
+ local kernels = {};
+ local i = 0;
+ if k ~= nil then
+ i = i + 1;
+ kernels[i] = k;
+ end
+
+ for n in v:gmatch("([^; ]+)[; ]?") do
+ if n ~= k then
+ i = i + 1;
+ kernels[i] = n;
+ end
+ end
+ return kernels;
+end
+
+function core.setDefaults()
+ core.setACPI(true);
+ core.setSafeMode(false);
+ core.setSingleUser(false);
+ core.setVerbose(false);
+end
+
+function core.autoboot()
+ loader.perform("autoboot");
+end
+
+function core.boot()
+ loader.perform("boot");
+end
+
+function core.bootserial()
+ local c = loader.getenv("console");
+
+ if c ~= nil then
+ if c:find("comconsole") ~= nil then
+ return true;
+ end
+ end
+
+ local s = loader.getenv("boot_serial");
+ if s ~= nil then
+ return true;
+ end
+
+ local m = loader.getenv("boot_multicons");
+ if m ~= nil then
+ return true;
+ end
+ return false;
+end
+
+return core
Index: stand/lua/drawer.lua
===================================================================
--- /dev/null
+++ stand/lua/drawer.lua
@@ -0,0 +1,309 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local drawer = {};
+
+local color = require("color");
+local screen = require("screen");
+
+drawer.brand_position = {x = 2, y = 1};
+drawer.fbsd_logo = {
+ " ______ ____ _____ _____ ",
+ " | ____| | _ \\ / ____| __ \\ ",
+ " | |___ _ __ ___ ___ | |_) | (___ | | | |",
+ " | ___| '__/ _ \\/ _ \\| _ < \\___ \\| | | |",
+ " | | | | | __/ __/| |_) |____) | |__| |",
+ " | | | | | | || | | |",
+ " |_| |_| \\___|\\___||____/|_____/|_____/ "
+};
+
+drawer.logo_position = {x = 46, y = 1};
+drawer.beastie_color = {
+ " \027[31m, ,",
+ " /( )`",
+ " \\ \\___ / |",
+ " /- \027[37m_\027[31m `-/ '",
+ " (\027[37m/\\/ \\\027[31m \\ /\\",
+ " \027[37m/ / |\027[31m ` \\",
+ " \027[34mO O \027[37m) \027[31m/ |",
+ " \027[37m`-^--'\027[31m`< '",
+ " (_.) _ ) /",
+ " `.___/` /",
+ " `-----' /",
+ " \027[33m<----.\027[31m __ / __ \\",
+ " \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|",
+ " \027[33m<----'\027[31m `--' `.__,' \\",
+ " | |",
+ " \\ / /\\",
+ " \027[36m______\027[31m( (_ / \\______/",
+ " \027[36m,' ,-----' |",
+ " `--{__________)\027[37m"
+};
+
+drawer.beastie = {
+ " , ,",
+ " /( )`",
+ " \\ \\___ / |",
+ " /- _ `-/ '",
+ " (/\\/ \\ \\ /\\",
+ " / / | ` \\",
+ " O O ) / |",
+ " `-^--'`< '",
+ " (_.) _ ) /",
+ " `.___/` /",
+ " `-----' /",
+ " <----. __ / __ \\",
+ " <----|====O)))==) \\) /====|",
+ " <----' `--' `.__,' \\",
+ " | |",
+ " \\ / /\\",
+ " ______( (_ / \\______/",
+ " ,' ,-----' |",
+ " `--{__________)"
+};
+
+drawer.fbsd_logo_shift = {x = 5, y = 4};
+drawer.fbsd_logo_v = {
+ " ______",
+ " | ____| __ ___ ___ ",
+ " | |__ | '__/ _ \\/ _ \\",
+ " | __|| | | __/ __/",
+ " | | | | | | |",
+ " |_| |_| \\___|\\___|",
+ " ____ _____ _____",
+ " | _ \\ / ____| __ \\",
+ " | |_) | (___ | | | |",
+ " | _ < \\___ \\| | | |",
+ " | |_) |____) | |__| |",
+ " | | | |",
+ " |____/|_____/|_____/"
+};
+
+drawer.orb_shift = {x = 2, y = 4};
+drawer.orb_color = {
+ " \027[31m``` \027[31;1m`\027[31m",
+ " s` `.....---...\027[31;1m....--.``` -/\027[31m",
+ " +o .--` \027[31;1m/y:` +.\027[31m",
+ " yo`:. \027[31;1m:o `+-\027[31m",
+ " y/ \027[31;1m-/` -o/\027[31m",
+ " .- \027[31;1m::/sy+:.\027[31m",
+ " / \027[31;1m`-- /\027[31m",
+ " `: \027[31;1m:`\027[31m",
+ " `: \027[31;1m:`\027[31m",
+ " / \027[31;1m/\027[31m",
+ " .- \027[31;1m-.\027[31m",
+ " -- \027[31;1m-.\027[31m",
+ " `:` \027[31;1m`:`",
+ " \027[31;1m.-- `--.",
+ " .---.....----.\027[37m"
+};
+
+drawer.orb = {
+ " ``` `",
+ " s` `.....---.......--.``` -/",
+ " +o .--` /y:` +.",
+ " yo`:. :o `+-",
+ " y/ -/` -o/",
+ " .- ::/sy+:.",
+ " / `-- /",
+ " `: :`",
+ " `: :`",
+ " / /",
+ " .- -.",
+ " -- -.",
+ " `:` `:`",
+ " .-- `--.",
+ " .---.....----."
+};
+
+drawer.none = {""};
+
+drawer.none_shift = {x = 17, y = 0};
+
+drawer.menu_position = {x = 6, y = 11};
+
+drawer.box_pos_dim = {x = 3, y = 10, w = 41, h = 11};
+
+function drawer.drawscreen(menu_opts)
+ -- drawlogo() must go first.
+ -- it determines the positions of other elements
+ drawer.drawlogo();
+ drawer.drawbrand();
+ drawer.drawbox();
+ return drawer.drawmenu(menu_opts);
+end
+
+function drawer.drawmenu(m)
+ x = drawer.menu_position.x;
+ y = drawer.menu_position.y;
+
+ -- print the menu and build the alias table
+ local alias_table = {};
+ local entry_num = 0;
+ for line_num, e in ipairs(m) do
+ if (e.entry_type ~= "separator") then
+ entry_num = entry_num + 1;
+ screen.setcursor(x, y + line_num);
+ print(entry_num .. ". "..e.name());
+
+ -- fill the alias table
+ alias_table[tostring(entry_num)] = e;
+ for n, a in ipairs(e.alias) do
+ alias_table[a] = e;
+ end
+ else
+ screen.setcursor(x, y + line_num);
+ print(e.name());
+ end
+ end
+ return alias_table;
+end
+
+
+function drawer.drawbox()
+ x = drawer.box_pos_dim.x;
+ y = drawer.box_pos_dim.y;
+ w = drawer.box_pos_dim.w;
+ h = drawer.box_pos_dim.h;
+
+ local hl = string.char(0xCD);
+ local vl = string.char(0xBA);
+
+ local tl = string.char(0xC9);
+ local bl = string.char(0xC8);
+ local tr = string.char(0xBB);
+ local br = string.char(0xBC);
+
+ screen.setcursor(x, y); print(tl);
+ screen.setcursor(x, y+h); print(bl);
+ screen.setcursor(x+w, y); print(tr);
+ screen.setcursor(x+w, y+h); print(br);
+
+ for i = 1, w-1 do
+ screen.setcursor(x+i, y);
+ print(hl);
+ screen.setcursor(x+i, y+h);
+ print(hl);
+ end
+
+ for i = 1, h-1 do
+ screen.setcursor(x, y+i);
+ print(vl);
+ screen.setcursor(x+w, y+i);
+ print(vl);
+ end
+
+ screen.setcursor(x+(w/2)-9, y);
+ print("Welcome to FreeBSD");
+end
+
+function drawer.draw(x, y, logo)
+ for i = 1, #logo do
+ screen.setcursor(x, y + i);
+ print(logo[i]);
+ end
+end
+
+function drawer.drawbrand()
+ local x = tonumber(loader.getenv("loader_brand_x"));
+ local y = tonumber(loader.getenv("loader_brand_y"));
+
+ if not x then
+ x = drawer.brand_position.x;
+ end
+ if not y then
+ y = drawer.brand_position.y;
+ end
+
+ local logo = load("return " .. tostring(loader.getenv("loader_brand")))();
+ if not logo then
+ logo = drawer.fbsd_logo;
+ end
+ drawer.draw(x, y, logo);
+end
+
+function drawer.drawlogo()
+ local x = tonumber(loader.getenv("loader_logo_x"));
+ local y = tonumber(loader.getenv("loader_logo_y"));
+
+ if not x then
+ x = drawer.logo_position.x;
+ end
+ if not y then
+ y = drawer.logo_position.y;
+ end
+
+ local logo = loader.getenv("loader_logo");
+ local s = {x = 0, y = 0};
+ local colored = color.isEnabled();
+
+ if logo == "beastie" then
+ if colored then
+ logo = drawer.beastie_color;
+ end
+ elseif logo == "beastiebw" then
+ logo = drawer.beastie;
+ elseif logo == "fbsdbw" then
+ logo = drawer.fbsd_logo_v;
+ s = drawer.fbsd_logo_shift;
+ elseif logo == "orb" then
+ if colored then
+ logo = drawer.orb_color;
+ end
+ s = drawer.orb_shift;
+ elseif logo == "orbbw" then
+ logo = drawer.orb;
+ s = drawer.orb_shift;
+ elseif logo == "tribute" then
+ logo = drawer.fbsd_logo;
+ elseif logo == "tributebw" then
+ logo = drawer.fbsd_logo;
+ elseif logo == "none" then
+ --centre brand and text if no logo
+ drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
+ drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
+ drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
+ drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
+ drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
+ drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
+ --prevent redraws from moving menu further
+ drawer.none_shift.x = 0;
+ drawer.none_shift.y = 0;
+ logo = drawer.none;
+ end
+ if not logo then
+ if colored then
+ logo = drawer.orb_color;
+ else
+ logo = drawer.orb;
+ end
+ end
+ drawer.draw(x + s.x, y + s.y, logo);
+end
+
+return drawer
Index: stand/lua/loader.lua
===================================================================
--- /dev/null
+++ stand/lua/loader.lua
@@ -0,0 +1,35 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+config = require("config");
+menu = require("menu");
+password = require("password");
+
+config.load();
+password.check();
+menu.run();
Index: stand/lua/menu.lua
===================================================================
--- /dev/null
+++ stand/lua/menu.lua
@@ -0,0 +1,379 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+
+local menu = {};
+
+local core = require("core");
+local color = require("color");
+local config = require("config");
+local screen = require("screen");
+local drawer = require("drawer");
+
+local OnOff;
+local skip;
+local run;
+local autoboot;
+
+--loader menu tree:
+--rooted at menu.welcome
+--submenu declarations:
+local kernel_options;
+local boot_options;
+local welcome;
+
+menu.kernel_options = {
+ -- this table is dynamically appended to when accessed
+ -- return to welcome menu
+ {
+ entry_type = "return",
+ name = function()
+ return "Back to main menu"..color.highlight(" [Backspace]");
+ end,
+ alias = {"\08"}
+ }
+};
+
+menu.boot_options = {
+ -- return to welcome menu
+ {
+ entry_type = "return",
+ name = function()
+ return "Back to main menu"..color.highlight(" [Backspace]");
+ end,
+ alias = {"\08"}
+ },
+
+ -- load defaults
+ {
+ entry_type = "entry",
+ name = function()
+ return "Load System "..color.highlight("D").."efaults";
+ end,
+ func = function()
+ core.setDefaults()
+ end,
+ alias = {"d", "D"}
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "";
+ end
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "Boot Options:";
+ end
+ },
+
+ -- acpi
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("A").."CPI :", core.acpi);
+ end,
+ func = function()
+ core.setACPI();
+ end,
+ alias = {"a", "A"}
+ },
+ -- safe mode
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff("Safe "..color.highlight("M").."ode :", core.sm);
+ end,
+ func = function()
+ core.setSafeMode();
+ end,
+ alias = {"m", "M"}
+ },
+ -- single user
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("S").."ingle user:", core.su);
+ end,
+ func = function()
+ core.setSingleUser();
+ end,
+ alias = {"s", "S"}
+ },
+ -- verbose boot
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("V").."erbose :", core.verbose);
+ end,
+ func = function()
+ core.setVerbose();
+ end,
+ alias = {"v", "V"}
+ },
+};
+
+menu.welcome = {
+ -- boot multi user
+ {
+ entry_type = "entry",
+ name = function()
+ return color.highlight("B").."oot Multi user "..color.highlight("[Enter]");
+ end,
+ func = function()
+ core.setSingleUser(false);
+ core.boot();
+ end,
+ alias = {"b", "B", "\013"}
+ },
+
+ -- boot single user
+ {
+ entry_type = "entry",
+ name = function()
+ return "Boot "..color.highlight("S").."ingle user";
+ end,
+ func = function()
+ core.setSingleUser(true);
+ core.boot();
+ end,
+ alias = {"s", "S"}
+ },
+
+ -- escape to interpreter
+ {
+ entry_type = "return",
+ name = function()
+ return color.highlight("Esc").."ape to lua interpreter";
+ end,
+ alias = {"\027"}
+ },
+
+ -- reboot
+ {
+ entry_type = "entry",
+ name = function()
+ return color.highlight("R").."eboot";
+ end,
+ func = function()
+ loader.perform("reboot");
+ end,
+ alias = {"r", "R"}
+ },
+
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "";
+ end
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "Options:";
+ end
+ },
+
+ -- kernel options
+ {
+ entry_type = "submenu",
+ name = function()
+ local kernels = core.kernelList();
+ if #kernels == 0 then
+ return "Kernels (not available)";
+ end
+ return color.highlight("K").."ernels";
+ end,
+ submenu = function()
+
+ -- dynamically build the kernel menu:
+ local kernels = core.kernelList();
+ for k, v in ipairs(kernels) do
+ menu.kernel_options[#menu.kernel_options + 1] = {
+ entry_type = "entry",
+ name = function()
+ return v;
+ end,
+ func = function()
+ config.reload(v);
+ end,
+ alias = {} -- automatically enumerated
+ }
+ end
+
+ return menu.kernel_options;
+ end,
+ alias = {"k", "K"}
+ },
+
+ -- boot options
+ {
+ entry_type = "submenu",
+ name = function()
+ return "Boot "..color.highlight("O").."ptions";
+ end,
+ submenu = function()
+ return menu.boot_options;
+ end,
+ alias = {"o", "O"}
+ }
+
+};
+
+function menu.run(m)
+
+ if (menu.skip()) then
+ core.autoboot();
+ return false;
+ end
+
+ if (m == nil) then
+ m = menu.welcome;
+ end
+
+ -- redraw screen
+ screen.clear();
+ screen.defcursor();
+ local alias_table = drawer.drawscreen(m);
+
+-- menu.autoboot();
+
+ cont = true;
+ while cont do
+ local key = string.char(io.getchar());
+
+ -- check to see if key is an alias
+ local sel_entry = nil;
+ for k, v in pairs(alias_table) do
+ if (key == k) then
+ sel_entry = v;
+ end
+ end
+
+ -- if we have an alias do the assigned action:
+ if(sel_entry ~= nil) then
+ if (sel_entry.entry_type == "entry") then
+ -- run function
+ sel_entry.func();
+ elseif (sel_entry.entry_type == "submenu") then
+ -- recurse
+ cont = menu.run(sel_entry.submenu());
+ elseif (sel_entry.entry_type == "return") then
+ -- break recurse
+ cont = false;
+ end
+ -- if we got an alias key the screen is out of date:
+ screen.clear();
+ screen.defcursor();
+ alias_table = drawer.drawscreen(m);
+ end
+ end
+
+ if (m == menu.welcome) then
+ screen.defcursor();
+ print("Exiting menu!");
+ return false;
+ end
+
+ return true;
+end
+
+function menu.skip()
+ if core.bootserial() then
+ return true;
+ end
+ local c = string.lower(loader.getenv("console") or "");
+ if (c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil then
+ return true;
+ end
+
+ c = string.lower(loader.getenv("beastie_disable") or "");
+ print("beastie_disable", c);
+ return c == "yes";
+end
+
+function menu.autoboot()
+ if menu.already_autoboot == true then
+ return;
+ end
+ menu.already_autoboot = true;
+
+ local ab = loader.getenv("autoboot_delay");
+ if ab == "NO" or ab == "no" then
+ core.boot();
+ end
+ ab = tonumber(ab) or 10;
+
+ local x = loader.getenv("loader_menu_timeout_x") or 5;
+ local y = loader.getenv("loader_menu_timeout_y") or 22;
+
+ local endtime = loader.time() + ab;
+ local time;
+
+ repeat
+ time = endtime - loader.time();
+ screen.setcursor(x, y);
+ print("Autoboot in "..time.." seconds, hit [Enter] to boot"
+ .." or any other key to stop ");
+ screen.defcursor();
+ if io.ischar() then
+ local ch = io.getchar();
+ if ch == 13 then
+ break;
+ else
+ -- prevent autoboot when escaping to interpreter
+ loader.setenv("autoboot_delay", "NO");
+ -- erase autoboot msg
+ screen.setcursor(0, y);
+ print(" "
+ .." ");
+ screen.defcursor();
+ return;
+ end
+ end
+
+ loader.delay(50000);
+ until time <= 0
+ core.boot();
+
+end
+
+function OnOff(str, b)
+ if (b) then
+ return str .. color.escapef(color.GREEN).."On"..color.escapef(color.WHITE);
+ else
+ return str .. color.escapef(color.RED).."off"..color.escapef(color.WHITE);
+ end
+end
+
+return menu
Index: stand/lua/password.lua
===================================================================
--- /dev/null
+++ stand/lua/password.lua
@@ -0,0 +1,85 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local password = {};
+
+local core = require("core");
+local screen = require("screen");
+
+function password.read()
+ local str = "";
+ local n = 0;
+
+ repeat
+ ch = io.getchar();
+ if ch == 13 then
+ break;
+ end
+
+ if ch == 8 then
+ if n > 0 then
+ n = n - 1;
+ -- loader.printc("\008 \008");
+ str = string.sub(str, 1, n);
+ end
+ else
+ -- loader.printc("*");
+ str = str .. string.char(ch);
+ n = n + 1;
+ end
+ until n == 16
+ return str;
+end
+
+function password.check()
+ screen.defcursor();
+ local function compare(prompt, pwd)
+ if (pwd == nil) then
+ return;
+ end
+ while true do
+ loader.printc(prompt);
+ if (pwd == password.read()) then
+ break;
+ end
+ print("\n\nloader: incorrect password!\n");
+ loader.delay(3*1000*1000);
+ end
+ end
+
+ local boot_pwd = loader.getenv("bootlock_password");
+ compare("Boot password: ", boot_pwd);
+
+ local pwd = loader.getenv("password");
+ if (pwd ~=nil) then
+ core.autoboot();
+ end
+ compare("Password: ", pwd);
+end
+
+return password
Index: stand/lua/screen.lua
===================================================================
--- /dev/null
+++ stand/lua/screen.lua
@@ -0,0 +1,73 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local screen = {};
+
+local color = require("color");
+local core = require("core");
+
+function screen.clear()
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027[H\027[J");
+end
+
+function screen.setcursor(x, y)
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027["..y..";"..x.."H");
+end
+
+function screen.setforeground(c)
+ if color.disabled then
+ return c;
+ end
+ loader.printc("\027[3"..c.."m");
+end
+
+function screen.setbackground(c)
+ if color.disabled then
+ return c;
+ end
+ loader.printc("\027[4"..c.."m");
+end
+
+function screen.defcolor()
+ loader.printc(color.default());
+end
+
+function screen.defcursor()
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027[25;0H");
+end
+
+return screen

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 13, 6:47 AM (11 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23629785
Default Alt Text
D14295.id39150.diff (40 KB)

Event Timeline