1088b4f5fSWarner Losh-- 272e39d71SKyle Evans-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD 372e39d71SKyle Evans-- 4088b4f5fSWarner Losh-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 521d5bcbeSKyle Evans-- Copyright (C) 2018 Kyle Evans <kevans@FreeBSD.org> 6088b4f5fSWarner Losh-- All rights reserved. 7088b4f5fSWarner Losh-- 8088b4f5fSWarner Losh-- Redistribution and use in source and binary forms, with or without 9088b4f5fSWarner Losh-- modification, are permitted provided that the following conditions 10088b4f5fSWarner Losh-- are met: 11088b4f5fSWarner Losh-- 1. Redistributions of source code must retain the above copyright 12088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer. 13088b4f5fSWarner Losh-- 2. Redistributions in binary form must reproduce the above copyright 14088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer in the 15088b4f5fSWarner Losh-- documentation and/or other materials provided with the distribution. 16088b4f5fSWarner Losh-- 17088b4f5fSWarner Losh-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18088b4f5fSWarner Losh-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19088b4f5fSWarner Losh-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20088b4f5fSWarner Losh-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21088b4f5fSWarner Losh-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22088b4f5fSWarner Losh-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23088b4f5fSWarner Losh-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24088b4f5fSWarner Losh-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25088b4f5fSWarner Losh-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26088b4f5fSWarner Losh-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27088b4f5fSWarner Losh-- SUCH DAMAGE. 28088b4f5fSWarner Losh-- 29088b4f5fSWarner Losh-- $FreeBSD$ 30088b4f5fSWarner Losh-- 31088b4f5fSWarner Losh 32088b4f5fSWarner Losh 33aedd6be5SKyle Evanslocal core = require("core") 34aedd6be5SKyle Evanslocal color = require("color") 35aedd6be5SKyle Evanslocal config = require("config") 36aedd6be5SKyle Evanslocal screen = require("screen") 37aedd6be5SKyle Evanslocal drawer = require("drawer") 38088b4f5fSWarner Losh 39aedd6be5SKyle Evanslocal menu = {} 40c8518398SKyle Evans 419ed6f9efSKyle Evanslocal function OnOff(str, b) 429f71d421SKyle Evans if b then 43e15abd1fSKyle Evans return str .. color.escapef(color.GREEN) .. "On" .. 44aedd6be5SKyle Evans color.escapef(color.WHITE) 45e15abd1fSKyle Evans else 46e15abd1fSKyle Evans return str .. color.escapef(color.RED) .. "off" .. 47aedd6be5SKyle Evans color.escapef(color.WHITE) 48e15abd1fSKyle Evans end 49e15abd1fSKyle Evansend 50e15abd1fSKyle Evans 519ed6f9efSKyle Evanslocal function bootenvSet(env) 527efc058fSKyle Evans loader.setenv("vfs.root.mountfrom", env) 537efc058fSKyle Evans loader.setenv("currdev", env .. ":") 547efc058fSKyle Evans config.reload() 557efc058fSKyle Evansend 567efc058fSKyle Evans 57b5746545SKyle Evans-- Module exports 588d415029SKyle Evansmenu.handlers = { 598d415029SKyle Evans -- Menu handlers take the current menu and selected entry as parameters, 608d415029SKyle Evans -- and should return a boolean indicating whether execution should 618d415029SKyle Evans -- continue or not. The return value may be omitted if this entry should 628d415029SKyle Evans -- have no bearing on whether we continue or not, indicating that we 638d415029SKyle Evans -- should just continue after execution. 64e2df27e3SKyle Evans [core.MENU_ENTRY] = function(_, entry) 658d415029SKyle Evans -- run function 66aedd6be5SKyle Evans entry.func() 678d415029SKyle Evans end, 68e2df27e3SKyle Evans [core.MENU_CAROUSEL_ENTRY] = function(_, entry) 698d415029SKyle Evans -- carousel (rotating) functionality 70aedd6be5SKyle Evans local carid = entry.carousel_id 71aedd6be5SKyle Evans local caridx = config.getCarouselIndex(carid) 724f437f9eSKyle Evans local choices = entry.items 734f437f9eSKyle Evans if type(choices) == "function" then 744f437f9eSKyle Evans choices = choices() 754f437f9eSKyle Evans end 769f71d421SKyle Evans if #choices > 0 then 77aedd6be5SKyle Evans caridx = (caridx % #choices) + 1 78aedd6be5SKyle Evans config.setCarouselIndex(carid, caridx) 79aedd6be5SKyle Evans entry.func(caridx, choices[caridx], choices) 808d415029SKyle Evans end 818d415029SKyle Evans end, 82e2df27e3SKyle Evans [core.MENU_SUBMENU] = function(_, entry) 838d415029SKyle Evans -- recurse 84*da9ab827SKyle Evans menu.process(entry.submenu) 858d415029SKyle Evans end, 86e2df27e3SKyle Evans [core.MENU_RETURN] = function(_, entry) 878d415029SKyle Evans -- allow entry to have a function/side effect 889f71d421SKyle Evans if entry.func ~= nil then 89aedd6be5SKyle Evans entry.func() 908d415029SKyle Evans end 91aedd6be5SKyle Evans return false 928d415029SKyle Evans end, 93aedd6be5SKyle Evans} 94280e990bSKyle Evans-- loader menu tree is rooted at menu.welcome 95088b4f5fSWarner Losh 967efc058fSKyle Evansmenu.boot_environments = { 977efc058fSKyle Evans entries = { 987efc058fSKyle Evans -- return to welcome menu 997efc058fSKyle Evans { 1007efc058fSKyle Evans entry_type = core.MENU_RETURN, 1017efc058fSKyle Evans name = "Back to main menu" .. 1027efc058fSKyle Evans color.highlight(" [Backspace]"), 1037efc058fSKyle Evans }, 1047efc058fSKyle Evans { 1057efc058fSKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 1067efc058fSKyle Evans carousel_id = "be_active", 1077efc058fSKyle Evans items = core.bootenvList, 1087efc058fSKyle Evans name = function(idx, choice, all_choices) 1097efc058fSKyle Evans if #all_choices == 0 then 1107efc058fSKyle Evans return "Active: " 1117efc058fSKyle Evans end 1127efc058fSKyle Evans 1137efc058fSKyle Evans local is_default = (idx == 1) 1147efc058fSKyle Evans local bootenv_name = "" 1157efc058fSKyle Evans local name_color 1167efc058fSKyle Evans if is_default then 1177efc058fSKyle Evans name_color = color.escapef(color.GREEN) 1187efc058fSKyle Evans else 1197efc058fSKyle Evans name_color = color.escapef(color.BLUE) 1207efc058fSKyle Evans end 1217efc058fSKyle Evans bootenv_name = bootenv_name .. name_color .. 1227efc058fSKyle Evans choice .. color.default() 1237efc058fSKyle Evans return color.highlight("A").."ctive: " .. 1247efc058fSKyle Evans bootenv_name .. " (" .. idx .. " of " .. 1257efc058fSKyle Evans #all_choices .. ")" 1267efc058fSKyle Evans end, 127e2df27e3SKyle Evans func = function(_, choice, _) 1287efc058fSKyle Evans bootenvSet(choice) 1297efc058fSKyle Evans end, 1307efc058fSKyle Evans alias = {"a", "A"}, 1317efc058fSKyle Evans }, 1327efc058fSKyle Evans { 1337efc058fSKyle Evans entry_type = core.MENU_ENTRY, 1347efc058fSKyle Evans name = function() 1357efc058fSKyle Evans return color.highlight("b") .. "ootfs: " .. 1367efc058fSKyle Evans core.bootenvDefault() 1377efc058fSKyle Evans end, 1387efc058fSKyle Evans func = function() 1397efc058fSKyle Evans -- Reset active boot environment to the default 1407efc058fSKyle Evans config.setCarouselIndex("be_active", 1) 1417efc058fSKyle Evans bootenvSet(core.bootenvDefault()) 1427efc058fSKyle Evans end, 1437efc058fSKyle Evans alias = {"b", "B"}, 1447efc058fSKyle Evans }, 1457efc058fSKyle Evans }, 1467efc058fSKyle Evans} 1477efc058fSKyle Evans 148088b4f5fSWarner Loshmenu.boot_options = { 149d8757746SKyle Evans entries = { 150088b4f5fSWarner Losh -- return to welcome menu 151088b4f5fSWarner Losh { 152a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 153a51f9f0cSKyle Evans name = "Back to main menu" .. 154a51f9f0cSKyle Evans color.highlight(" [Backspace]"), 155088b4f5fSWarner Losh }, 156088b4f5fSWarner Losh -- load defaults 157088b4f5fSWarner Losh { 158a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 159a51f9f0cSKyle Evans name = "Load System " .. color.highlight("D") .. 160a51f9f0cSKyle Evans "efaults", 161a51f9f0cSKyle Evans func = core.setDefaults, 1623cd5547bSKyle Evans alias = {"d", "D"}, 163088b4f5fSWarner Losh }, 164088b4f5fSWarner Losh { 165a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 166088b4f5fSWarner Losh }, 167088b4f5fSWarner Losh { 168a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 169a51f9f0cSKyle Evans name = "Boot Options:", 170088b4f5fSWarner Losh }, 171088b4f5fSWarner Losh -- acpi 172088b4f5fSWarner Losh { 173a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 174c1ab36f5SKyle Evans visible = core.isSystem386, 175088b4f5fSWarner Losh name = function() 176fd2b19b3SKyle Evans return OnOff(color.highlight("A") .. 177aedd6be5SKyle Evans "CPI :", core.acpi) 178088b4f5fSWarner Losh end, 179a51f9f0cSKyle Evans func = core.setACPI, 1803cd5547bSKyle Evans alias = {"a", "A"}, 181088b4f5fSWarner Losh }, 182088b4f5fSWarner Losh -- safe mode 183088b4f5fSWarner Losh { 184a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 185088b4f5fSWarner Losh name = function() 18657099121SKyle Evans return OnOff("Safe " .. color.highlight("M") .. 187aedd6be5SKyle Evans "ode :", core.sm) 188088b4f5fSWarner Losh end, 189a51f9f0cSKyle Evans func = core.setSafeMode, 1903cd5547bSKyle Evans alias = {"m", "M"}, 191088b4f5fSWarner Losh }, 192088b4f5fSWarner Losh -- single user 193088b4f5fSWarner Losh { 194a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 195088b4f5fSWarner Losh name = function() 196fd2b19b3SKyle Evans return OnOff(color.highlight("S") .. 197aedd6be5SKyle Evans "ingle user:", core.su) 198088b4f5fSWarner Losh end, 199a51f9f0cSKyle Evans func = core.setSingleUser, 2003cd5547bSKyle Evans alias = {"s", "S"}, 201088b4f5fSWarner Losh }, 202088b4f5fSWarner Losh -- verbose boot 203088b4f5fSWarner Losh { 204a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 205088b4f5fSWarner Losh name = function() 206fd2b19b3SKyle Evans return OnOff(color.highlight("V") .. 207aedd6be5SKyle Evans "erbose :", core.verbose) 208088b4f5fSWarner Losh end, 209a51f9f0cSKyle Evans func = core.setVerbose, 2103cd5547bSKyle Evans alias = {"v", "V"}, 211088b4f5fSWarner Losh }, 212d8757746SKyle Evans }, 213aedd6be5SKyle Evans} 214088b4f5fSWarner Losh 215088b4f5fSWarner Loshmenu.welcome = { 216303253e5SKyle Evans entries = function() 217aedd6be5SKyle Evans local menu_entries = menu.welcome.all_entries 218303253e5SKyle Evans -- Swap the first two menu items on single user boot 2199f71d421SKyle Evans if core.isSingleUserBoot() then 2209a0904b0SKyle Evans -- We'll cache the swapped menu, for performance 2219f71d421SKyle Evans if menu.welcome.swapped_menu ~= nil then 222aedd6be5SKyle Evans return menu.welcome.swapped_menu 2239a0904b0SKyle Evans end 2245c1b5165SKyle Evans -- Shallow copy the table 225ee4e69f1SKyle Evans menu_entries = core.deepCopyTable(menu_entries) 2265c1b5165SKyle Evans 2279a0904b0SKyle Evans -- Swap the first two menu entries 2284b6da14cSKyle Evans menu_entries[1], menu_entries[2] = 229aedd6be5SKyle Evans menu_entries[2], menu_entries[1] 230303253e5SKyle Evans 2319a0904b0SKyle Evans -- Then set their names to their alternate names 2329a0904b0SKyle Evans menu_entries[1].name, menu_entries[2].name = 2339a0904b0SKyle Evans menu_entries[1].alternate_name, 234aedd6be5SKyle Evans menu_entries[2].alternate_name 235aedd6be5SKyle Evans menu.welcome.swapped_menu = menu_entries 236303253e5SKyle Evans end 237aedd6be5SKyle Evans return menu_entries 238303253e5SKyle Evans end, 239303253e5SKyle Evans all_entries = { 240088b4f5fSWarner Losh -- boot multi user 241088b4f5fSWarner Losh { 242a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 243a51f9f0cSKyle Evans name = color.highlight("B") .. "oot Multi user " .. 244a51f9f0cSKyle Evans color.highlight("[Enter]"), 2455c1b5165SKyle Evans -- Not a standard menu entry function! 246a51f9f0cSKyle Evans alternate_name = color.highlight("B") .. 247a51f9f0cSKyle Evans "oot Multi user", 248088b4f5fSWarner Losh func = function() 249aedd6be5SKyle Evans core.setSingleUser(false) 250aedd6be5SKyle Evans core.boot() 251088b4f5fSWarner Losh end, 2523cd5547bSKyle Evans alias = {"b", "B"}, 253088b4f5fSWarner Losh }, 254088b4f5fSWarner Losh -- boot single user 255088b4f5fSWarner Losh { 256a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 257a51f9f0cSKyle Evans name = "Boot " .. color.highlight("S") .. "ingle user", 2585c1b5165SKyle Evans -- Not a standard menu entry function! 259a51f9f0cSKyle Evans alternate_name = "Boot " .. color.highlight("S") .. 260a51f9f0cSKyle Evans "ingle user " .. color.highlight("[Enter]"), 261088b4f5fSWarner Losh func = function() 262aedd6be5SKyle Evans core.setSingleUser(true) 263aedd6be5SKyle Evans core.boot() 264088b4f5fSWarner Losh end, 2653cd5547bSKyle Evans alias = {"s", "S"}, 266088b4f5fSWarner Losh }, 267088b4f5fSWarner Losh -- escape to interpreter 268088b4f5fSWarner Losh { 269a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 270a51f9f0cSKyle Evans name = color.highlight("Esc") .. "ape to loader prompt", 271ef625845SKyle Evans func = function() 272aedd6be5SKyle Evans loader.setenv("autoboot_delay", "NO") 273ef625845SKyle Evans end, 2743cd5547bSKyle Evans alias = {core.KEYSTR_ESCAPE}, 275088b4f5fSWarner Losh }, 276088b4f5fSWarner Losh -- reboot 277088b4f5fSWarner Losh { 278a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 279a51f9f0cSKyle Evans name = color.highlight("R") .. "eboot", 280088b4f5fSWarner Losh func = function() 281aedd6be5SKyle Evans loader.perform("reboot") 282088b4f5fSWarner Losh end, 2833cd5547bSKyle Evans alias = {"r", "R"}, 284088b4f5fSWarner Losh }, 285088b4f5fSWarner Losh { 286a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 287088b4f5fSWarner Losh }, 288088b4f5fSWarner Losh { 289a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 290a51f9f0cSKyle Evans name = "Options:", 291088b4f5fSWarner Losh }, 292088b4f5fSWarner Losh -- kernel options 293088b4f5fSWarner Losh { 294a7cf0562SKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 295ada26c4aSKyle Evans carousel_id = "kernel", 296ada26c4aSKyle Evans items = core.kernelList, 297ada26c4aSKyle Evans name = function(idx, choice, all_choices) 2989f71d421SKyle Evans if #all_choices == 0 then 299aedd6be5SKyle Evans return "Kernel: " 300088b4f5fSWarner Losh end 301b1b1f2b8SKyle Evans 302aedd6be5SKyle Evans local is_default = (idx == 1) 303aedd6be5SKyle Evans local kernel_name = "" 304aedd6be5SKyle Evans local name_color 3059f71d421SKyle Evans if is_default then 306aedd6be5SKyle Evans name_color = color.escapef(color.GREEN) 307aedd6be5SKyle Evans kernel_name = "default/" 308bcf48a15SKyle Evans else 309aedd6be5SKyle Evans name_color = color.escapef(color.BLUE) 310b1b1f2b8SKyle Evans end 311fd2b19b3SKyle Evans kernel_name = kernel_name .. name_color .. 312aedd6be5SKyle Evans choice .. color.default() 313fd2b19b3SKyle Evans return color.highlight("K") .. "ernel: " .. 314fd2b19b3SKyle Evans kernel_name .. " (" .. idx .. " of " .. 315aedd6be5SKyle Evans #all_choices .. ")" 316088b4f5fSWarner Losh end, 317e2df27e3SKyle Evans func = function(_, choice, _) 318322a2dddSKyle Evans config.selectKernel(choice) 319088b4f5fSWarner Losh end, 3203cd5547bSKyle Evans alias = {"k", "K"}, 321088b4f5fSWarner Losh }, 322088b4f5fSWarner Losh -- boot options 323088b4f5fSWarner Losh { 324a7cf0562SKyle Evans entry_type = core.MENU_SUBMENU, 325a51f9f0cSKyle Evans name = "Boot " .. color.highlight("O") .. "ptions", 3269a28f948SKyle Evans submenu = menu.boot_options, 3273cd5547bSKyle Evans alias = {"o", "O"}, 328d8757746SKyle Evans }, 3297efc058fSKyle Evans -- boot environments 3307efc058fSKyle Evans { 3317efc058fSKyle Evans entry_type = core.MENU_SUBMENU, 3327efc058fSKyle Evans visible = function() 3337efc058fSKyle Evans return core.isZFSBoot() and 3347efc058fSKyle Evans #core.bootenvList() > 1 3357efc058fSKyle Evans end, 3367efc058fSKyle Evans name = "Boot " .. color.highlight("E") .. "nvironments", 3377efc058fSKyle Evans submenu = menu.boot_environments, 3387efc058fSKyle Evans alias = {"e", "E"}, 3397efc058fSKyle Evans }, 340d8757746SKyle Evans }, 341aedd6be5SKyle Evans} 342088b4f5fSWarner Losh 34320a81676SKyle Evansmenu.default = menu.welcome 34420a81676SKyle Evans 345*da9ab827SKyle Evansfunction menu.process(m) 346*da9ab827SKyle Evans assert(m ~= nil) 347088b4f5fSWarner Losh -- redraw screen 348aedd6be5SKyle Evans screen.clear() 349aedd6be5SKyle Evans screen.defcursor() 350aedd6be5SKyle Evans local alias_table = drawer.drawscreen(m) 351088b4f5fSWarner Losh 352*da9ab827SKyle Evans -- autoboot processing likely belongs better in menu.run, but we want 353*da9ab827SKyle Evans -- to draw the menu once before we do any autoboot prompting. We also 354*da9ab827SKyle Evans -- collect the alias table from the drawer, which generates the table 355*da9ab827SKyle Evans -- based on all of the 'alias' entries along with effective line numbers 356*da9ab827SKyle Evans -- that each entry is drawn at. This makes it cleaner to handle here, 357*da9ab827SKyle Evans -- for the time being. 3587dcffa90SKyle Evans local autoboot_key; 3597dcffa90SKyle Evans if m == menu.default then 3607dcffa90SKyle Evans autoboot_key = menu.autoboot() 3617dcffa90SKyle Evans end 362*da9ab827SKyle Evans while true do 36312b95c84SKyle Evans local key = autoboot_key or io.getchar() 36412b95c84SKyle Evans autoboot_key = nil 365088b4f5fSWarner Losh 366b458bf0dSKyle Evans -- Special key behaviors 3679f71d421SKyle Evans if (key == core.KEY_BACKSPACE or key == core.KEY_DELETE) and 36820a81676SKyle Evans m ~= menu.default then 369aedd6be5SKyle Evans break 3709f71d421SKyle Evans elseif key == core.KEY_ENTER then 371aedd6be5SKyle Evans core.boot() 372b458bf0dSKyle Evans -- Should not return 373abc4f7e7SKyle Evans end 374abc4f7e7SKyle Evans 375abc4f7e7SKyle Evans key = string.char(key) 376088b4f5fSWarner Losh -- check to see if key is an alias 377aedd6be5SKyle Evans local sel_entry = nil 378088b4f5fSWarner Losh for k, v in pairs(alias_table) do 3799f71d421SKyle Evans if key == k then 380aedd6be5SKyle Evans sel_entry = v 381088b4f5fSWarner Losh end 382088b4f5fSWarner Losh end 383088b4f5fSWarner Losh 384088b4f5fSWarner Losh -- if we have an alias do the assigned action: 3859f71d421SKyle Evans if sel_entry ~= nil then 3868d415029SKyle Evans -- Get menu handler 387aedd6be5SKyle Evans local handler = menu.handlers[sel_entry.entry_type] 3889f71d421SKyle Evans if handler ~= nil then 389*da9ab827SKyle Evans -- The handler's return value indicates if we 390*da9ab827SKyle Evans -- need to exit this menu. An omitted or true 391*da9ab827SKyle Evans -- return value means to continue. 392*da9ab827SKyle Evans if handler(m, sel_entry) == false then 393*da9ab827SKyle Evans return 394aefcaa7eSKyle Evans end 395088b4f5fSWarner Losh end 396088b4f5fSWarner Losh -- if we got an alias key the screen is out of date: 397aedd6be5SKyle Evans screen.clear() 398aedd6be5SKyle Evans screen.defcursor() 399aedd6be5SKyle Evans alias_table = drawer.drawscreen(m) 400088b4f5fSWarner Losh end 401088b4f5fSWarner Losh end 402088b4f5fSWarner Loshend 403088b4f5fSWarner Losh 404*da9ab827SKyle Evansfunction menu.run() 405*da9ab827SKyle Evans if menu.skip() then 406*da9ab827SKyle Evans core.autoboot() 407*da9ab827SKyle Evans return 408*da9ab827SKyle Evans end 409*da9ab827SKyle Evans 410*da9ab827SKyle Evans menu.process(menu.default) 411*da9ab827SKyle Evans 412*da9ab827SKyle Evans screen.defcursor() 413*da9ab827SKyle Evans print("Exiting menu!") 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) 45966964bbcSKyle 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