Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Feb 2018 15:32:00 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r329167 - in head/stand: . lua
Message-ID:  <201802121532.w1CFW0U2007475@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Mon Feb 12 15:32:00 2018
New Revision: 329167
URL: https://svnweb.freebsd.org/changeset/base/329167

Log:
  Add the lua scripts from the lua-bootloader SoC
  
  These are the .lua files from from Pedro Souza's 2014 Summer of Code
  project. Rui Paulo, Pedro Arthur and Wojciech A. Koszek also
  contributed.
  
  Obtained from: https://wiki.freebsd.org/SummerOfCode2014/LuaLoader
  Sponsored by: Google Summer of Code
  
  Improve the SoC lua menu code to bring it in line with forth
  menu functionality
  
  Submitted by: Zakary Nafziger
  Sponsored by: FreeBSD Foundation
  
  Use loader.setenv and loader.unsetenv instead of loader.perform
  
  Convert from include("/boot/foo.lua") to foo = require("foo");
  to bring in line with latest lua module conventions.
  
  Enforce a uniform style for the new .lua files:
  	o hard tab indenation for 8 spaces
  	o don't have if foo then bar; else bas; end on one line
  
  MFC After: 1 month
  Relnotes: yes
  Differential Review: https://reviews.freebsd.org/D14295

Added:
  head/stand/lua/
  head/stand/lua/Makefile   (contents, props changed)
  head/stand/lua/color.lua   (contents, props changed)
  head/stand/lua/config.lua   (contents, props changed)
  head/stand/lua/core.lua   (contents, props changed)
  head/stand/lua/drawer.lua   (contents, props changed)
  head/stand/lua/loader.lua   (contents, props changed)
  head/stand/lua/menu.lua   (contents, props changed)
  head/stand/lua/password.lua   (contents, props changed)
  head/stand/lua/screen.lua   (contents, props changed)
Modified:
  head/stand/Makefile

Modified: head/stand/Makefile
==============================================================================
--- head/stand/Makefile	Mon Feb 12 15:31:53 2018	(r329166)
+++ head/stand/Makefile	Mon Feb 12 15:32:00 2018	(r329167)
@@ -10,6 +10,7 @@ SUBDIR+=		forth
 .endif
 .if ${MK_LOADER_LUA} != "no"
 SUBDIR+=		liblua
+SUBDIR+=		lua
 .endif
 
 SUBDIR+=		man

Added: head/stand/lua/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/Makefile	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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>

Added: head/stand/lua/color.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/color.lua	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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

Added: head/stand/lua/config.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/config.lua	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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

Added: head/stand/lua/core.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/core.lua	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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

Added: head/stand/lua/drawer.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/drawer.lua	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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

Added: head/stand/lua/loader.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/stand/lua/loader.lua	Mon Feb 12 15:32:00 2018	(r329167)
@@ -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.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802121532.w1CFW0U2007475>