Index: head/stand/lua/color.lua =================================================================== --- head/stand/lua/color.lua (revision 329434) +++ head/stand/lua/color.lua (revision 329435) @@ -1,99 +1,98 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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 + if (c ~= nil) then + if (c:lower() == "no") or (c == "0") then return false; end end - return not core.bootserial(); + return (not core.bootserial()); end -color.disabled = not color.isEnabled(); +color.disabled = (not color.isEnabled()); - function color.escapef(c) - if color.disabled then + if (color.disabled) then return c; end return "\027[3"..c.."m"; end function color.escapeb(c) - if color.disabled then + if (color.disabled) then return c; end return "\027[4"..c.."m"; end function color.escape(fg, bg, att) - if color.disabled then + if (color.disabled) then return ""; end - if not att then + 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 + if (color.disabled) then return ""; end return "\027[0;37;40m"; end function color.highlight(str) - if color.disabled then + if (color.disabled) then return str; end return "\027[1m"..str.."\027[0m"; end -return color +return color; Index: head/stand/lua/config.lua =================================================================== --- head/stand/lua/config.lua (revision 329434) +++ head/stand/lua/config.lua (revision 329435) @@ -1,388 +1,388 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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 function config.dumpModules() print("== Dumping modules"); for k, v in pairs(modules) do print(k, v.load); end print("== Dump ended"); 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 = v:upper(); 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 = c:match("^%s*#.*"); if s == nil then s = c:match("^%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 text:gmatch("([^\n]+)") do if line:match("^%s*$") == nil then local found = false; for i, val in ipairs(pattern_table) do local k, v, c = line:match(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 -- other_kernel is optionally the name of a kernel to load, if not the default -- or autoloaded default from the module_path function config.loadkernel(other_kernel) local flags = loader.getenv("kernel_options") or ""; local kernel = other_kernel or 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; + 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("No kernel set, failed to load from module_path"); return false; end else local module_path = loader.getenv("module_path"); local res = nil; if other_kern ~= nil then kernel = other_kern; end -- 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 if module_path ~= nil then loader.setenv("module_path", v..";".. module_path); end 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 '"..kernel.."'"); 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 f:gmatch("([%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 configured modules..."); if not config.loadmod(modules) then print("Could not load one or more modules!"); end end function config.reload(kernel) local kernel_loaded = false; -- unload all modules print("Unloading modules..."); loader.perform("unload"); if (kernel ~= nil) then print("Trying to load '" .. kernel .. "'") kernel_loaded = config.loadkernel(kernel); if (kernel_loaded) then print("Kernel '"..kernel.."' loaded!"); end end -- failed to load kernel or it is nil -- then load default if (not kernel_loaded) then print("Loading default kernel..."); config.loadkernel(); end -- load modules config.loadmod(modules); end return config Index: head/stand/lua/core.lua =================================================================== --- head/stand/lua/core.lua (revision 329434) +++ head/stand/lua/core.lua (revision 329435) @@ -1,182 +1,182 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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 = {}; -- Commonly appearing constants core.KEY_BACKSPACE = 8; core.KEY_ENTER = 13; core.KEY_DELETE = 127; core.KEYSTR_ESCAPE = "\027"; core.MENU_RETURN = "return"; core.MENU_ENTRY = "entry"; core.MENU_SEPARATOR = "separator"; core.MENU_SUBMENU = "submenu"; core.MENU_CAROUSEL_ENTRY = "carousel_entry"; 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.getACPIPresent(checkingSystemDefaults) local c = loader.getenv("hint.acpi.0.rsdp"); if (c ~= nil) then if (checkingSystemDefaults == true) then return true; end -- Otherwise, respect disabled if it's set c = loader.getenv("hint.acpi.0.disabled"); return (c == nil) or (tonumber(c) ~= 1); end return false; 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 + if (k ~= nil) then i = i + 1; kernels[i] = k; end for n in v:gmatch("([^; ]+)[; ]?") do - if n ~= k then + if (n ~= k) then i = i + 1; kernels[i] = n; end end return kernels; end function core.setDefaults() core.setACPI(core.getACPIPresent(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 + if (c ~= nil) then + if (c:find("comconsole") ~= nil) then return true; end end local s = loader.getenv("boot_serial"); - if s ~= nil then + if (s ~= nil) then return true; end local m = loader.getenv("boot_multicons"); - if m ~= nil then + if (m ~= nil) then return true; end return false; end -core.setACPI(core.getACPIPresent(false)) -return core +core.setACPI(core.getACPIPresent(false)); +return core; Index: head/stand/lua/drawer.lua =================================================================== --- head/stand/lua/drawer.lua (revision 329434) +++ head/stand/lua/drawer.lua (revision 329435) @@ -1,326 +1,314 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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 core = require("core"); 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 ~= core.MENU_SEPARATOR) then entry_num = entry_num + 1; screen.setcursor(x, y + line_num); local name = ""; if (e.entry_type == core.MENU_CAROUSEL_ENTRY) then local carid = e.carousel_id; local caridx = menu.getCarouselIndex(carid); local choices = e.items(); if (#choices < caridx) then caridx = 1; - end; + end name = e.name(caridx, choices[caridx], choices); else name = e.name(); end print(entry_num .. ". "..name); -- fill the alias table alias_table[tostring(entry_num)] = e; if (e.alias ~= nil) then for n, a in ipairs(e.alias) do alias_table[a] = e; end 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")); + local x = tonumber(loader.getenv("loader_brand_x")) or + drawer.brand_position.x; + local y = tonumber(loader.getenv("loader_brand_y")) or + drawer.brand_position.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 + local logo = load("return " .. tostring(loader.getenv("loader_brand")))() or + drawer.fbsd_logo; 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")); + local x = tonumber(loader.getenv("loader_logo_x")) or + drawer.logo_position.x; + local y = tonumber(loader.getenv("loader_logo_y")) or + drawer.logo_position.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 + if (logo == "beastie") then + if (colored) then logo = drawer.beastie_color; end - elseif logo == "beastiebw" then + elseif (logo == "beastiebw") then logo = drawer.beastie; - elseif logo == "fbsdbw" then + elseif (logo == "fbsdbw") then logo = drawer.fbsd_logo_v; s = drawer.fbsd_logo_shift; - elseif logo == "orb" then - if colored then + elseif (logo == "orb") then + if (colored) then logo = drawer.orb_color; end s = drawer.orb_shift; - elseif logo == "orbbw" then + elseif (logo == "orbbw") then logo = drawer.orb; s = drawer.orb_shift; - elseif logo == "tribute" then + elseif (logo == "tribute") then logo = drawer.fbsd_logo; - elseif logo == "tributebw" then + elseif (logo == "tributebw") then logo = drawer.fbsd_logo; - elseif logo == "none" then + 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 + 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 +return drawer; Index: head/stand/lua/menu.lua =================================================================== --- head/stand/lua/menu.lua (revision 329434) +++ head/stand/lua/menu.lua (revision 329435) @@ -1,409 +1,409 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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; local carousel_choices = {}; --loader menu tree: --rooted at menu.welcome --submenu declarations: local boot_options; local welcome; menu.boot_options = { -- return to welcome menu { entry_type = core.MENU_RETURN, name = function() return "Back to main menu"..color.highlight(" [Backspace]"); end }, -- load defaults { entry_type = core.MENU_ENTRY, name = function() return "Load System "..color.highlight("D").."efaults"; end, func = function() - core.setDefaults() + core.setDefaults(); end, alias = {"d", "D"} }, { entry_type = core.MENU_SEPARATOR, name = function() return ""; end }, { entry_type = core.MENU_SEPARATOR, name = function() return "Boot Options:"; end }, -- acpi { entry_type = core.MENU_ENTRY, name = function() return OnOff(color.highlight("A").."CPI :", core.acpi); end, func = function() core.setACPI(); end, alias = {"a", "A"} }, -- safe mode { entry_type = core.MENU_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 = core.MENU_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 = core.MENU_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 = core.MENU_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"} }, -- boot single user { entry_type = core.MENU_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 = core.MENU_RETURN, name = function() return color.highlight("Esc").."ape to loader prompt"; end, func = function() - loader.setenv("autoboot_delay", "NO") + loader.setenv("autoboot_delay", "NO"); end, alias = {core.KEYSTR_ESCAPE} }, -- reboot { entry_type = core.MENU_ENTRY, name = function() return color.highlight("R").."eboot"; end, func = function() loader.perform("reboot"); end, alias = {"r", "R"} }, { entry_type = core.MENU_SEPARATOR, name = function() return ""; end }, { entry_type = core.MENU_SEPARATOR, name = function() return "Options:"; end }, -- kernel options { entry_type = core.MENU_CAROUSEL_ENTRY, carousel_id = "kernel", items = core.kernelList, name = function(idx, choice, all_choices) - if #all_choices == 0 then + if (#all_choices == 0) then return "Kernel: "; end local is_default = (idx == 1); local kernel_name = ""; local name_color; - if is_default then + if (is_default) then name_color = color.escapef(color.GREEN); kernel_name = "default/"; else name_color = color.escapef(color.BLUE); end kernel_name = kernel_name .. name_color .. choice .. color.default(); return color.highlight("K").."ernel: " .. kernel_name .. " (" .. idx .. " of " .. #all_choices .. ")"; end, func = function(idx, choice, all_choices) if (#all_choices > 1) then config.reload(choice); end end, alias = {"k", "K"} }, -- boot options { entry_type = core.MENU_SUBMENU, name = function() return "Boot "..color.highlight("O").."ptions"; end, submenu = function() return menu.boot_options; end, alias = {"o", "O"} } }; -- The first item in every carousel is always the default item. function menu.getCarouselIndex(id) local val = carousel_choices[id]; if (val == nil) then return 1; end return val; end function menu.setCarouselIndex(id, idx) carousel_choices[id] = idx; end 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 + while (cont) do local key = io.getchar(); -- Special key behaviors if ((key == core.KEY_BACKSPACE) or (key == core.KEY_DELETE)) and (m ~= menu.welcome) then break elseif (key == core.KEY_ENTER) then core.boot(); -- Should not return end key = string.char(key) -- 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 ~= nil) then if (sel_entry.entry_type == core.MENU_ENTRY) then -- run function sel_entry.func(); elseif (sel_entry.entry_type == core.MENU_CAROUSEL_ENTRY) then -- carousel (rotating) functionality local carid = sel_entry.carousel_id; local caridx = menu.getCarouselIndex(carid); local choices = sel_entry.items(); if (#choices > 0) then caridx = (caridx % #choices) + 1; menu.setCarouselIndex(carid, caridx); sel_entry.func(caridx, choices[caridx], choices); end elseif (sel_entry.entry_type == core.MENU_SUBMENU) then -- recurse cont = menu.run(sel_entry.submenu()); elseif (sel_entry.entry_type == core.MENU_RETURN) then -- allow entry to have a function/side effect if (sel_entry.func ~= nil) then sel_entry.func(); end -- 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 + 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 + 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 + if (menu.already_autoboot == true) then return; end menu.already_autoboot = true; local ab = loader.getenv("autoboot_delay"); if (ab ~= nil) and (ab:lower() == "no") then return; elseif (tonumber(ab) == -1) 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 + if (io.ischar()) then local ch = io.getchar(); - if ch == core.KEY_ENTER then + if (ch == core.KEY_ENTER) then break; else -- 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 +return menu; Index: head/stand/lua/password.lua =================================================================== --- head/stand/lua/password.lua (revision 329434) +++ head/stand/lua/password.lua (revision 329435) @@ -1,99 +1,99 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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 == core.KEY_ENTER then + if (ch == core.KEY_ENTER) then break; end -- XXX TODO: Evaluate if we really want this or not, as a -- security consideration of sorts if (ch == core.KEY_BACKSPACE) or (ch == core.KEY_DELETE) then - if n > 0 then + if (n > 0) then n = n - 1; -- loader.printc("\008 \008"); - str = string.sub(str, 1, n); + str = str:sub(1, n); end else -- loader.printc("*"); str = str .. string.char(ch); n = n + 1; end - until n == 16 + until (n == 16); return str; end function password.check() screen.defcursor(); -- pwd is optionally supplied if we want to check it local function do_prompt(prompt, pwd) - while true do + while (true) do loader.printc(prompt); local read_pwd = password.read(); if (not pwd) or (pwd == read_pwd) then + -- Throw an extra newline after password prompt + print(""); return read_pwd; end print("\n\nloader: incorrect password!\n"); loader.delay(3*1000*1000); end - -- Throw an extra newline out after the password prompt - print("") end local function compare(prompt, pwd) if (pwd == nil) then return; end do_prompt(prompt, pwd); end - local boot_pwd = loader.getenv("bootlock_password"); + local boot_pwd = "boot" --loader.getenv("bootlock_password"); compare("Boot password: ", boot_pwd); local geli_prompt = loader.getenv("geom_eli_passphrase_prompt"); if (geli_prompt ~= nil) and (geli_prompt:lower() == "yes") then local passphrase = do_prompt("GELI Passphrase: "); - loader.setenv("kern.geom.eli.passphrase", passphrase) + loader.setenv("kern.geom.eli.passphrase", passphrase); end local pwd = loader.getenv("password"); - if (pwd ~=nil) then + if (pwd ~= nil) then core.autoboot(); end compare("Password: ", pwd); end -return password +return password; Index: head/stand/lua/screen.lua =================================================================== --- head/stand/lua/screen.lua (revision 329434) +++ head/stand/lua/screen.lua (revision 329435) @@ -1,85 +1,85 @@ -- -- Copyright (c) 2015 Pedro Souza -- 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"); -- XXX TODO: This should be fixed in the interpreter to not print decimals function intstring(num) - local str = tostring(num) - local decimal = string.find(str, "%.") + local str = tostring(num); + local decimal = str:find("%."); - if decimal then - return string.sub(str, 1, decimal - 1) + if (decimal) then + return str:sub(1, decimal - 1); end - return str + return str; end function screen.clear() - if core.bootserial() then + if (core.bootserial()) then return; end loader.printc("\027[H\027[J"); end function screen.setcursor(x, y) - if core.bootserial() then + if (core.bootserial()) then return; end loader.printc("\027["..intstring(y)..";"..intstring(x).."H"); end function screen.setforeground(c) - if color.disabled then + if (color.disabled) then return c; end loader.printc("\027[3"..c.."m"); end function screen.setbackground(c) - if color.disabled then + 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 + if (core.bootserial()) then return; end loader.printc("\027[25;0H"); end -return screen +return screen;