1088b4f5fSWarner Losh-- 2088b4f5fSWarner Losh-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 321d5bcbeSKyle Evans-- Copyright (C) 2018 Kyle Evans <kevans@FreeBSD.org> 4088b4f5fSWarner Losh-- All rights reserved. 5088b4f5fSWarner Losh-- 6088b4f5fSWarner Losh-- Redistribution and use in source and binary forms, with or without 7088b4f5fSWarner Losh-- modification, are permitted provided that the following conditions 8088b4f5fSWarner Losh-- are met: 9088b4f5fSWarner Losh-- 1. Redistributions of source code must retain the above copyright 10088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer. 11088b4f5fSWarner Losh-- 2. Redistributions in binary form must reproduce the above copyright 12088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer in the 13088b4f5fSWarner Losh-- documentation and/or other materials provided with the distribution. 14088b4f5fSWarner Losh-- 15088b4f5fSWarner Losh-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16088b4f5fSWarner Losh-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17088b4f5fSWarner Losh-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18088b4f5fSWarner Losh-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19088b4f5fSWarner Losh-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20088b4f5fSWarner Losh-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21088b4f5fSWarner Losh-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22088b4f5fSWarner Losh-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23088b4f5fSWarner Losh-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24088b4f5fSWarner Losh-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25088b4f5fSWarner Losh-- SUCH DAMAGE. 26088b4f5fSWarner Losh-- 27088b4f5fSWarner Losh-- $FreeBSD$ 28088b4f5fSWarner Losh-- 29088b4f5fSWarner Losh 30088b4f5fSWarner Losh 31aedd6be5SKyle Evanslocal core = require("core") 32aedd6be5SKyle Evanslocal color = require("color") 33aedd6be5SKyle Evanslocal config = require("config") 34aedd6be5SKyle Evanslocal screen = require("screen") 35aedd6be5SKyle Evanslocal drawer = require("drawer") 36088b4f5fSWarner Losh 37aedd6be5SKyle Evanslocal menu = {} 38c8518398SKyle Evans 39e15abd1fSKyle Evanslocal OnOff = function(str, b) 409f71d421SKyle Evans if b then 41e15abd1fSKyle Evans return str .. color.escapef(color.GREEN) .. "On" .. 42aedd6be5SKyle Evans color.escapef(color.WHITE) 43e15abd1fSKyle Evans else 44e15abd1fSKyle Evans return str .. color.escapef(color.RED) .. "off" .. 45aedd6be5SKyle Evans color.escapef(color.WHITE) 46e15abd1fSKyle Evans end 47e15abd1fSKyle Evansend 48e15abd1fSKyle Evans 497efc058fSKyle Evanslocal bootenvSet = function(env) 507efc058fSKyle Evans loader.setenv("vfs.root.mountfrom", env) 517efc058fSKyle Evans loader.setenv("currdev", env .. ":") 527efc058fSKyle Evans config.reload() 537efc058fSKyle Evansend 547efc058fSKyle Evans 55b5746545SKyle Evans-- Module exports 568d415029SKyle Evansmenu.handlers = { 578d415029SKyle Evans -- Menu handlers take the current menu and selected entry as parameters, 588d415029SKyle Evans -- and should return a boolean indicating whether execution should 598d415029SKyle Evans -- continue or not. The return value may be omitted if this entry should 608d415029SKyle Evans -- have no bearing on whether we continue or not, indicating that we 618d415029SKyle Evans -- should just continue after execution. 62e2df27e3SKyle Evans [core.MENU_ENTRY] = function(_, entry) 638d415029SKyle Evans -- run function 64aedd6be5SKyle Evans entry.func() 658d415029SKyle Evans end, 66e2df27e3SKyle Evans [core.MENU_CAROUSEL_ENTRY] = function(_, entry) 678d415029SKyle Evans -- carousel (rotating) functionality 68aedd6be5SKyle Evans local carid = entry.carousel_id 69aedd6be5SKyle Evans local caridx = config.getCarouselIndex(carid) 704f437f9eSKyle Evans local choices = entry.items 714f437f9eSKyle Evans if type(choices) == "function" then 724f437f9eSKyle Evans choices = choices() 734f437f9eSKyle Evans end 749f71d421SKyle Evans if #choices > 0 then 75aedd6be5SKyle Evans caridx = (caridx % #choices) + 1 76aedd6be5SKyle Evans config.setCarouselIndex(carid, caridx) 77aedd6be5SKyle Evans entry.func(caridx, choices[caridx], choices) 788d415029SKyle Evans end 798d415029SKyle Evans end, 80e2df27e3SKyle Evans [core.MENU_SUBMENU] = function(_, entry) 818d415029SKyle Evans -- recurse 829a28f948SKyle Evans return menu.run(entry.submenu) 838d415029SKyle Evans end, 84e2df27e3SKyle Evans [core.MENU_RETURN] = function(_, entry) 858d415029SKyle Evans -- allow entry to have a function/side effect 869f71d421SKyle Evans if entry.func ~= nil then 87aedd6be5SKyle Evans entry.func() 888d415029SKyle Evans end 89aedd6be5SKyle Evans return false 908d415029SKyle Evans end, 91aedd6be5SKyle Evans} 92280e990bSKyle Evans-- loader menu tree is rooted at menu.welcome 93088b4f5fSWarner Losh 947efc058fSKyle Evansmenu.boot_environments = { 957efc058fSKyle Evans entries = { 967efc058fSKyle Evans -- return to welcome menu 977efc058fSKyle Evans { 987efc058fSKyle Evans entry_type = core.MENU_RETURN, 997efc058fSKyle Evans name = "Back to main menu" .. 1007efc058fSKyle Evans color.highlight(" [Backspace]"), 1017efc058fSKyle Evans }, 1027efc058fSKyle Evans { 1037efc058fSKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 1047efc058fSKyle Evans carousel_id = "be_active", 1057efc058fSKyle Evans items = core.bootenvList, 1067efc058fSKyle Evans name = function(idx, choice, all_choices) 1077efc058fSKyle Evans if #all_choices == 0 then 1087efc058fSKyle Evans return "Active: " 1097efc058fSKyle Evans end 1107efc058fSKyle Evans 1117efc058fSKyle Evans local is_default = (idx == 1) 1127efc058fSKyle Evans local bootenv_name = "" 1137efc058fSKyle Evans local name_color 1147efc058fSKyle Evans if is_default then 1157efc058fSKyle Evans name_color = color.escapef(color.GREEN) 1167efc058fSKyle Evans else 1177efc058fSKyle Evans name_color = color.escapef(color.BLUE) 1187efc058fSKyle Evans end 1197efc058fSKyle Evans bootenv_name = bootenv_name .. name_color .. 1207efc058fSKyle Evans choice .. color.default() 1217efc058fSKyle Evans return color.highlight("A").."ctive: " .. 1227efc058fSKyle Evans bootenv_name .. " (" .. idx .. " of " .. 1237efc058fSKyle Evans #all_choices .. ")" 1247efc058fSKyle Evans end, 125e2df27e3SKyle Evans func = function(_, choice, _) 1267efc058fSKyle Evans bootenvSet(choice) 1277efc058fSKyle Evans end, 1287efc058fSKyle Evans alias = {"a", "A"}, 1297efc058fSKyle Evans }, 1307efc058fSKyle Evans { 1317efc058fSKyle Evans entry_type = core.MENU_ENTRY, 1327efc058fSKyle Evans name = function() 1337efc058fSKyle Evans return color.highlight("b") .. "ootfs: " .. 1347efc058fSKyle Evans core.bootenvDefault() 1357efc058fSKyle Evans end, 1367efc058fSKyle Evans func = function() 1377efc058fSKyle Evans -- Reset active boot environment to the default 1387efc058fSKyle Evans config.setCarouselIndex("be_active", 1) 1397efc058fSKyle Evans bootenvSet(core.bootenvDefault()) 1407efc058fSKyle Evans end, 1417efc058fSKyle Evans alias = {"b", "B"}, 1427efc058fSKyle Evans }, 1437efc058fSKyle Evans }, 1447efc058fSKyle Evans} 1457efc058fSKyle Evans 146088b4f5fSWarner Loshmenu.boot_options = { 147d8757746SKyle Evans entries = { 148088b4f5fSWarner Losh -- return to welcome menu 149088b4f5fSWarner Losh { 150a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 151a51f9f0cSKyle Evans name = "Back to main menu" .. 152a51f9f0cSKyle Evans color.highlight(" [Backspace]"), 153088b4f5fSWarner Losh }, 154088b4f5fSWarner Losh -- load defaults 155088b4f5fSWarner Losh { 156a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 157a51f9f0cSKyle Evans name = "Load System " .. color.highlight("D") .. 158a51f9f0cSKyle Evans "efaults", 159a51f9f0cSKyle Evans func = core.setDefaults, 160088b4f5fSWarner Losh alias = {"d", "D"} 161088b4f5fSWarner Losh }, 162088b4f5fSWarner Losh { 163a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 164088b4f5fSWarner Losh }, 165088b4f5fSWarner Losh { 166a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 167a51f9f0cSKyle Evans name = "Boot Options:", 168088b4f5fSWarner Losh }, 169088b4f5fSWarner Losh -- acpi 170088b4f5fSWarner Losh { 171a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 172c1ab36f5SKyle Evans visible = core.isSystem386, 173088b4f5fSWarner Losh name = function() 174fd2b19b3SKyle Evans return OnOff(color.highlight("A") .. 175aedd6be5SKyle Evans "CPI :", core.acpi) 176088b4f5fSWarner Losh end, 177a51f9f0cSKyle Evans func = core.setACPI, 178088b4f5fSWarner Losh alias = {"a", "A"} 179088b4f5fSWarner Losh }, 180088b4f5fSWarner Losh -- safe mode 181088b4f5fSWarner Losh { 182a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 183088b4f5fSWarner Losh name = function() 18457099121SKyle Evans return OnOff("Safe " .. color.highlight("M") .. 185aedd6be5SKyle Evans "ode :", core.sm) 186088b4f5fSWarner Losh end, 187a51f9f0cSKyle Evans func = core.setSafeMode, 188088b4f5fSWarner Losh alias = {"m", "M"} 189088b4f5fSWarner Losh }, 190088b4f5fSWarner Losh -- single user 191088b4f5fSWarner Losh { 192a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 193088b4f5fSWarner Losh name = function() 194fd2b19b3SKyle Evans return OnOff(color.highlight("S") .. 195aedd6be5SKyle Evans "ingle user:", core.su) 196088b4f5fSWarner Losh end, 197a51f9f0cSKyle Evans func = core.setSingleUser, 198088b4f5fSWarner Losh alias = {"s", "S"} 199088b4f5fSWarner Losh }, 200088b4f5fSWarner Losh -- verbose boot 201088b4f5fSWarner Losh { 202a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 203088b4f5fSWarner Losh name = function() 204fd2b19b3SKyle Evans return OnOff(color.highlight("V") .. 205aedd6be5SKyle Evans "erbose :", core.verbose) 206088b4f5fSWarner Losh end, 207a51f9f0cSKyle Evans func = core.setVerbose, 208088b4f5fSWarner Losh alias = {"v", "V"} 209088b4f5fSWarner Losh }, 210d8757746SKyle Evans }, 211aedd6be5SKyle Evans} 212088b4f5fSWarner Losh 213088b4f5fSWarner Loshmenu.welcome = { 214303253e5SKyle Evans entries = function() 215aedd6be5SKyle Evans local menu_entries = menu.welcome.all_entries 216303253e5SKyle Evans -- Swap the first two menu items on single user boot 2179f71d421SKyle Evans if core.isSingleUserBoot() then 2189a0904b0SKyle Evans -- We'll cache the swapped menu, for performance 2199f71d421SKyle Evans if menu.welcome.swapped_menu ~= nil then 220aedd6be5SKyle Evans return menu.welcome.swapped_menu 2219a0904b0SKyle Evans end 2225c1b5165SKyle Evans -- Shallow copy the table 223aedd6be5SKyle Evans menu_entries = core.shallowCopyTable(menu_entries) 2245c1b5165SKyle Evans 2259a0904b0SKyle Evans -- Swap the first two menu entries 2264b6da14cSKyle Evans menu_entries[1], menu_entries[2] = 227aedd6be5SKyle Evans menu_entries[2], menu_entries[1] 228303253e5SKyle Evans 2299a0904b0SKyle Evans -- Then set their names to their alternate names 2309a0904b0SKyle Evans menu_entries[1].name, menu_entries[2].name = 2319a0904b0SKyle Evans menu_entries[1].alternate_name, 232aedd6be5SKyle Evans menu_entries[2].alternate_name 233aedd6be5SKyle Evans menu.welcome.swapped_menu = menu_entries 234303253e5SKyle Evans end 235aedd6be5SKyle Evans return menu_entries 236303253e5SKyle Evans end, 237303253e5SKyle Evans all_entries = { 238088b4f5fSWarner Losh -- boot multi user 239088b4f5fSWarner Losh { 240a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 241a51f9f0cSKyle Evans name = color.highlight("B") .. "oot Multi user " .. 242a51f9f0cSKyle Evans color.highlight("[Enter]"), 2435c1b5165SKyle Evans -- Not a standard menu entry function! 244a51f9f0cSKyle Evans alternate_name = color.highlight("B") .. 245a51f9f0cSKyle Evans "oot Multi user", 246088b4f5fSWarner Losh func = function() 247aedd6be5SKyle Evans core.setSingleUser(false) 248aedd6be5SKyle Evans core.boot() 249088b4f5fSWarner Losh end, 250b458bf0dSKyle Evans alias = {"b", "B"} 251088b4f5fSWarner Losh }, 252088b4f5fSWarner Losh -- boot single user 253088b4f5fSWarner Losh { 254a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 255a51f9f0cSKyle Evans name = "Boot " .. color.highlight("S") .. "ingle user", 2565c1b5165SKyle Evans -- Not a standard menu entry function! 257a51f9f0cSKyle Evans alternate_name = "Boot " .. color.highlight("S") .. 258a51f9f0cSKyle Evans "ingle user " .. color.highlight("[Enter]"), 259088b4f5fSWarner Losh func = function() 260aedd6be5SKyle Evans core.setSingleUser(true) 261aedd6be5SKyle Evans core.boot() 262088b4f5fSWarner Losh end, 263088b4f5fSWarner Losh alias = {"s", "S"} 264088b4f5fSWarner Losh }, 265088b4f5fSWarner Losh -- escape to interpreter 266088b4f5fSWarner Losh { 267a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 268a51f9f0cSKyle Evans name = color.highlight("Esc") .. "ape to loader prompt", 269ef625845SKyle Evans func = function() 270aedd6be5SKyle Evans loader.setenv("autoboot_delay", "NO") 271ef625845SKyle Evans end, 27239006570SKyle Evans alias = {core.KEYSTR_ESCAPE} 273088b4f5fSWarner Losh }, 274088b4f5fSWarner Losh -- reboot 275088b4f5fSWarner Losh { 276a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 277a51f9f0cSKyle Evans name = color.highlight("R") .. "eboot", 278088b4f5fSWarner Losh func = function() 279aedd6be5SKyle Evans loader.perform("reboot") 280088b4f5fSWarner Losh end, 281088b4f5fSWarner Losh alias = {"r", "R"} 282088b4f5fSWarner Losh }, 283088b4f5fSWarner Losh { 284a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 285088b4f5fSWarner Losh }, 286088b4f5fSWarner Losh { 287a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 288a51f9f0cSKyle Evans name = "Options:", 289088b4f5fSWarner Losh }, 290088b4f5fSWarner Losh -- kernel options 291088b4f5fSWarner Losh { 292a7cf0562SKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 293ada26c4aSKyle Evans carousel_id = "kernel", 294ada26c4aSKyle Evans items = core.kernelList, 295ada26c4aSKyle Evans name = function(idx, choice, all_choices) 2969f71d421SKyle Evans if #all_choices == 0 then 297aedd6be5SKyle Evans return "Kernel: " 298088b4f5fSWarner Losh end 299b1b1f2b8SKyle Evans 300aedd6be5SKyle Evans local is_default = (idx == 1) 301aedd6be5SKyle Evans local kernel_name = "" 302aedd6be5SKyle Evans local name_color 3039f71d421SKyle Evans if is_default then 304aedd6be5SKyle Evans name_color = color.escapef(color.GREEN) 305aedd6be5SKyle Evans kernel_name = "default/" 306bcf48a15SKyle Evans else 307aedd6be5SKyle Evans name_color = color.escapef(color.BLUE) 308b1b1f2b8SKyle Evans end 309fd2b19b3SKyle Evans kernel_name = kernel_name .. name_color .. 310aedd6be5SKyle Evans choice .. color.default() 311fd2b19b3SKyle Evans return color.highlight("K") .. "ernel: " .. 312fd2b19b3SKyle Evans kernel_name .. " (" .. idx .. " of " .. 313aedd6be5SKyle Evans #all_choices .. ")" 314088b4f5fSWarner Losh end, 315e2df27e3SKyle Evans func = function(_, choice, _) 316aedd6be5SKyle Evans config.selectkernel(choice) 317088b4f5fSWarner Losh end, 318088b4f5fSWarner Losh alias = {"k", "K"} 319088b4f5fSWarner Losh }, 320088b4f5fSWarner Losh -- boot options 321088b4f5fSWarner Losh { 322a7cf0562SKyle Evans entry_type = core.MENU_SUBMENU, 323a51f9f0cSKyle Evans name = "Boot " .. color.highlight("O") .. "ptions", 3249a28f948SKyle Evans submenu = menu.boot_options, 325088b4f5fSWarner Losh alias = {"o", "O"} 326d8757746SKyle Evans }, 3277efc058fSKyle Evans -- boot environments 3287efc058fSKyle Evans { 3297efc058fSKyle Evans entry_type = core.MENU_SUBMENU, 3307efc058fSKyle Evans visible = function() 3317efc058fSKyle Evans return core.isZFSBoot() and 3327efc058fSKyle Evans #core.bootenvList() > 1 3337efc058fSKyle Evans end, 3347efc058fSKyle Evans name = "Boot " .. color.highlight("E") .. "nvironments", 3357efc058fSKyle Evans submenu = menu.boot_environments, 3367efc058fSKyle Evans alias = {"e", "E"}, 3377efc058fSKyle Evans }, 338d8757746SKyle Evans }, 339aedd6be5SKyle Evans} 340088b4f5fSWarner Losh 34120a81676SKyle Evansmenu.default = menu.welcome 34220a81676SKyle Evans 343088b4f5fSWarner Loshfunction menu.run(m) 344088b4f5fSWarner Losh 3459f71d421SKyle Evans if menu.skip() then 346aedd6be5SKyle Evans core.autoboot() 347aedd6be5SKyle Evans return false 348088b4f5fSWarner Losh end 349088b4f5fSWarner Losh 3509f71d421SKyle Evans if m == nil then 35120a81676SKyle Evans m = menu.default 352088b4f5fSWarner Losh end 353088b4f5fSWarner Losh 354088b4f5fSWarner Losh -- redraw screen 355aedd6be5SKyle Evans screen.clear() 356aedd6be5SKyle Evans screen.defcursor() 357aedd6be5SKyle Evans local alias_table = drawer.drawscreen(m) 358088b4f5fSWarner Losh 35912b95c84SKyle Evans -- Might return nil, that's ok 3607dcffa90SKyle Evans local autoboot_key; 3617dcffa90SKyle Evans if m == menu.default then 3627dcffa90SKyle Evans autoboot_key = menu.autoboot() 3637dcffa90SKyle Evans end 364e2df27e3SKyle Evans local cont = true 3659f71d421SKyle Evans while cont do 36612b95c84SKyle Evans local key = autoboot_key or io.getchar() 36712b95c84SKyle Evans autoboot_key = nil 368088b4f5fSWarner Losh 369b458bf0dSKyle Evans -- Special key behaviors 3709f71d421SKyle Evans if (key == core.KEY_BACKSPACE or key == core.KEY_DELETE) and 37120a81676SKyle Evans m ~= menu.default then 372aedd6be5SKyle Evans break 3739f71d421SKyle Evans elseif key == core.KEY_ENTER then 374aedd6be5SKyle Evans core.boot() 375b458bf0dSKyle Evans -- Should not return 376abc4f7e7SKyle Evans end 377abc4f7e7SKyle Evans 378abc4f7e7SKyle Evans key = string.char(key) 379088b4f5fSWarner Losh -- check to see if key is an alias 380aedd6be5SKyle Evans local sel_entry = nil 381088b4f5fSWarner Losh for k, v in pairs(alias_table) do 3829f71d421SKyle Evans if key == k then 383aedd6be5SKyle Evans sel_entry = v 384088b4f5fSWarner Losh end 385088b4f5fSWarner Losh end 386088b4f5fSWarner Losh 387088b4f5fSWarner Losh -- if we have an alias do the assigned action: 3889f71d421SKyle Evans if sel_entry ~= nil then 3898d415029SKyle Evans -- Get menu handler 390aedd6be5SKyle Evans local handler = menu.handlers[sel_entry.entry_type] 3919f71d421SKyle Evans if handler ~= nil then 3928d415029SKyle Evans -- The handler's return value indicates whether 3938d415029SKyle Evans -- we need to exit this menu. An omitted return 3948d415029SKyle Evans -- value means "continue" by default. 395aedd6be5SKyle Evans cont = handler(m, sel_entry) 3969f71d421SKyle Evans if cont == nil then 397aedd6be5SKyle Evans cont = true 398aefcaa7eSKyle Evans end 399088b4f5fSWarner Losh end 400088b4f5fSWarner Losh -- if we got an alias key the screen is out of date: 401aedd6be5SKyle Evans screen.clear() 402aedd6be5SKyle Evans screen.defcursor() 403aedd6be5SKyle Evans alias_table = drawer.drawscreen(m) 404088b4f5fSWarner Losh end 405088b4f5fSWarner Losh end 406088b4f5fSWarner Losh 40720a81676SKyle Evans if m == menu.default then 408aedd6be5SKyle Evans screen.defcursor() 409aedd6be5SKyle Evans print("Exiting menu!") 410aedd6be5SKyle Evans return false 411088b4f5fSWarner Losh end 412088b4f5fSWarner Losh 413aedd6be5SKyle Evans return true 414088b4f5fSWarner Loshend 415088b4f5fSWarner Losh 416088b4f5fSWarner Loshfunction menu.skip() 4179f71d421SKyle Evans if core.isSerialBoot() then 418aedd6be5SKyle Evans return true 419088b4f5fSWarner Losh end 420aedd6be5SKyle Evans local c = string.lower(loader.getenv("console") or "") 4219f71d421SKyle Evans if c:match("^efi[ ;]") ~= nil or c:match("[ ;]efi[ ;]") ~= nil then 422aedd6be5SKyle Evans return true 423088b4f5fSWarner Losh end 424088b4f5fSWarner Losh 425aedd6be5SKyle Evans c = string.lower(loader.getenv("beastie_disable") or "") 426aedd6be5SKyle Evans print("beastie_disable", c) 427aedd6be5SKyle Evans return c == "yes" 428088b4f5fSWarner Loshend 429088b4f5fSWarner Losh 430088b4f5fSWarner Loshfunction menu.autoboot() 431aedd6be5SKyle Evans local ab = loader.getenv("autoboot_delay") 4329f71d421SKyle Evans if ab ~= nil and ab:lower() == "no" then 43312b95c84SKyle Evans return nil 4349f71d421SKyle Evans elseif tonumber(ab) == -1 then 435aedd6be5SKyle Evans core.boot() 436088b4f5fSWarner Losh end 437aedd6be5SKyle Evans ab = tonumber(ab) or 10 438088b4f5fSWarner Losh 439aedd6be5SKyle Evans local x = loader.getenv("loader_menu_timeout_x") or 5 440aedd6be5SKyle Evans local y = loader.getenv("loader_menu_timeout_y") or 22 441088b4f5fSWarner Losh 442aedd6be5SKyle Evans local endtime = loader.time() + ab 443aedd6be5SKyle Evans local time 444088b4f5fSWarner Losh 445088b4f5fSWarner Losh repeat 446aedd6be5SKyle Evans time = endtime - loader.time() 447aedd6be5SKyle Evans screen.setcursor(x, y) 44857099121SKyle Evans print("Autoboot in " .. time .. 44957099121SKyle Evans " seconds, hit [Enter] to boot" .. 450aedd6be5SKyle Evans " or any other key to stop ") 451aedd6be5SKyle Evans screen.defcursor() 4529f71d421SKyle Evans if io.ischar() then 453aedd6be5SKyle Evans local ch = io.getchar() 4549f71d421SKyle Evans if ch == core.KEY_ENTER then 455aedd6be5SKyle Evans break 456088b4f5fSWarner Losh else 457088b4f5fSWarner Losh -- erase autoboot msg 458aedd6be5SKyle Evans screen.setcursor(0, y) 459*66964bbcSKyle Evans print(string.rep(" ", 80)) 460aedd6be5SKyle Evans screen.defcursor() 46112b95c84SKyle Evans return ch 462088b4f5fSWarner Losh end 463088b4f5fSWarner Losh end 464088b4f5fSWarner Losh 465aedd6be5SKyle Evans loader.delay(50000) 466aedd6be5SKyle Evans until time <= 0 467aedd6be5SKyle Evans core.boot() 468088b4f5fSWarner Losh 469088b4f5fSWarner Loshend 470088b4f5fSWarner Losh 471aedd6be5SKyle Evansreturn menu 472