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 41beafe961SKyle Evanslocal drawn_menu 42ca16d83fSKyle Evans 43*04af4229SKyle Evanslocal function OnOff(str, value) 44*04af4229SKyle Evans if value then 45e15abd1fSKyle Evans return str .. color.escapef(color.GREEN) .. "On" .. 46aedd6be5SKyle Evans color.escapef(color.WHITE) 47e15abd1fSKyle Evans else 48e15abd1fSKyle Evans return str .. color.escapef(color.RED) .. "off" .. 49aedd6be5SKyle Evans color.escapef(color.WHITE) 50e15abd1fSKyle Evans end 51e15abd1fSKyle Evansend 52e15abd1fSKyle Evans 539ed6f9efSKyle Evanslocal function bootenvSet(env) 547efc058fSKyle Evans loader.setenv("vfs.root.mountfrom", env) 557efc058fSKyle Evans loader.setenv("currdev", env .. ":") 567efc058fSKyle Evans config.reload() 577efc058fSKyle Evansend 587efc058fSKyle Evans 59b5746545SKyle Evans-- Module exports 608d415029SKyle Evansmenu.handlers = { 618d415029SKyle Evans -- Menu handlers take the current menu and selected entry as parameters, 628d415029SKyle Evans -- and should return a boolean indicating whether execution should 638d415029SKyle Evans -- continue or not. The return value may be omitted if this entry should 648d415029SKyle Evans -- have no bearing on whether we continue or not, indicating that we 658d415029SKyle Evans -- should just continue after execution. 66e2df27e3SKyle Evans [core.MENU_ENTRY] = function(_, entry) 678d415029SKyle Evans -- run function 68aedd6be5SKyle Evans entry.func() 698d415029SKyle Evans end, 70e2df27e3SKyle Evans [core.MENU_CAROUSEL_ENTRY] = function(_, entry) 718d415029SKyle Evans -- carousel (rotating) functionality 72aedd6be5SKyle Evans local carid = entry.carousel_id 73aedd6be5SKyle Evans local caridx = config.getCarouselIndex(carid) 744f437f9eSKyle Evans local choices = entry.items 754f437f9eSKyle Evans if type(choices) == "function" then 764f437f9eSKyle Evans choices = choices() 774f437f9eSKyle Evans end 789f71d421SKyle Evans if #choices > 0 then 79aedd6be5SKyle Evans caridx = (caridx % #choices) + 1 80aedd6be5SKyle Evans config.setCarouselIndex(carid, caridx) 81aedd6be5SKyle Evans entry.func(caridx, choices[caridx], choices) 828d415029SKyle Evans end 838d415029SKyle Evans end, 84e2df27e3SKyle Evans [core.MENU_SUBMENU] = function(_, entry) 85da9ab827SKyle Evans menu.process(entry.submenu) 868d415029SKyle Evans end, 87e2df27e3SKyle Evans [core.MENU_RETURN] = function(_, entry) 888d415029SKyle Evans -- allow entry to have a function/side effect 899f71d421SKyle Evans if entry.func ~= nil then 90aedd6be5SKyle Evans entry.func() 918d415029SKyle Evans end 92aedd6be5SKyle Evans return false 938d415029SKyle Evans end, 94aedd6be5SKyle Evans} 95280e990bSKyle Evans-- loader menu tree is rooted at menu.welcome 96088b4f5fSWarner Losh 977efc058fSKyle Evansmenu.boot_environments = { 987efc058fSKyle Evans entries = { 997efc058fSKyle Evans -- return to welcome menu 1007efc058fSKyle Evans { 1017efc058fSKyle Evans entry_type = core.MENU_RETURN, 1027efc058fSKyle Evans name = "Back to main menu" .. 1037efc058fSKyle Evans color.highlight(" [Backspace]"), 1047efc058fSKyle Evans }, 1057efc058fSKyle Evans { 1067efc058fSKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 1077efc058fSKyle Evans carousel_id = "be_active", 1087efc058fSKyle Evans items = core.bootenvList, 1097efc058fSKyle Evans name = function(idx, choice, all_choices) 1107efc058fSKyle Evans if #all_choices == 0 then 1117efc058fSKyle Evans return "Active: " 1127efc058fSKyle Evans end 1137efc058fSKyle Evans 1147efc058fSKyle Evans local is_default = (idx == 1) 1157efc058fSKyle Evans local bootenv_name = "" 1167efc058fSKyle Evans local name_color 1177efc058fSKyle Evans if is_default then 1187efc058fSKyle Evans name_color = color.escapef(color.GREEN) 1197efc058fSKyle Evans else 1207efc058fSKyle Evans name_color = color.escapef(color.BLUE) 1217efc058fSKyle Evans end 1227efc058fSKyle Evans bootenv_name = bootenv_name .. name_color .. 1237efc058fSKyle Evans choice .. color.default() 1247efc058fSKyle Evans return color.highlight("A").."ctive: " .. 1257efc058fSKyle Evans bootenv_name .. " (" .. idx .. " of " .. 1267efc058fSKyle Evans #all_choices .. ")" 1277efc058fSKyle Evans end, 128e2df27e3SKyle Evans func = function(_, choice, _) 1297efc058fSKyle Evans bootenvSet(choice) 1307efc058fSKyle Evans end, 1317efc058fSKyle Evans alias = {"a", "A"}, 1327efc058fSKyle Evans }, 1337efc058fSKyle Evans { 1347efc058fSKyle Evans entry_type = core.MENU_ENTRY, 1357efc058fSKyle Evans name = function() 1367efc058fSKyle Evans return color.highlight("b") .. "ootfs: " .. 1377efc058fSKyle Evans core.bootenvDefault() 1387efc058fSKyle Evans end, 1397efc058fSKyle Evans func = function() 1407efc058fSKyle Evans -- Reset active boot environment to the default 1417efc058fSKyle Evans config.setCarouselIndex("be_active", 1) 1427efc058fSKyle Evans bootenvSet(core.bootenvDefault()) 1437efc058fSKyle Evans end, 1447efc058fSKyle Evans alias = {"b", "B"}, 1457efc058fSKyle Evans }, 1467efc058fSKyle Evans }, 1477efc058fSKyle Evans} 1487efc058fSKyle Evans 149088b4f5fSWarner Loshmenu.boot_options = { 150d8757746SKyle Evans entries = { 151088b4f5fSWarner Losh -- return to welcome menu 152088b4f5fSWarner Losh { 153a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 154a51f9f0cSKyle Evans name = "Back to main menu" .. 155a51f9f0cSKyle Evans color.highlight(" [Backspace]"), 156088b4f5fSWarner Losh }, 157088b4f5fSWarner Losh -- load defaults 158088b4f5fSWarner Losh { 159a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 160a51f9f0cSKyle Evans name = "Load System " .. color.highlight("D") .. 161a51f9f0cSKyle Evans "efaults", 162a51f9f0cSKyle Evans func = core.setDefaults, 1633cd5547bSKyle Evans alias = {"d", "D"}, 164088b4f5fSWarner Losh }, 165088b4f5fSWarner Losh { 166a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 167088b4f5fSWarner Losh }, 168088b4f5fSWarner Losh { 169a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 170a51f9f0cSKyle Evans name = "Boot Options:", 171088b4f5fSWarner Losh }, 172088b4f5fSWarner Losh -- acpi 173088b4f5fSWarner Losh { 174a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 175c1ab36f5SKyle Evans visible = core.isSystem386, 176088b4f5fSWarner Losh name = function() 177fd2b19b3SKyle Evans return OnOff(color.highlight("A") .. 178aedd6be5SKyle Evans "CPI :", core.acpi) 179088b4f5fSWarner Losh end, 180a51f9f0cSKyle Evans func = core.setACPI, 1813cd5547bSKyle Evans alias = {"a", "A"}, 182088b4f5fSWarner Losh }, 183088b4f5fSWarner Losh -- safe mode 184088b4f5fSWarner Losh { 185a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 186088b4f5fSWarner Losh name = function() 18757099121SKyle Evans return OnOff("Safe " .. color.highlight("M") .. 188aedd6be5SKyle Evans "ode :", core.sm) 189088b4f5fSWarner Losh end, 190a51f9f0cSKyle Evans func = core.setSafeMode, 1913cd5547bSKyle Evans alias = {"m", "M"}, 192088b4f5fSWarner Losh }, 193088b4f5fSWarner Losh -- single user 194088b4f5fSWarner Losh { 195a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 196088b4f5fSWarner Losh name = function() 197fd2b19b3SKyle Evans return OnOff(color.highlight("S") .. 198aedd6be5SKyle Evans "ingle user:", core.su) 199088b4f5fSWarner Losh end, 200a51f9f0cSKyle Evans func = core.setSingleUser, 2013cd5547bSKyle Evans alias = {"s", "S"}, 202088b4f5fSWarner Losh }, 203088b4f5fSWarner Losh -- verbose boot 204088b4f5fSWarner Losh { 205a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 206088b4f5fSWarner Losh name = function() 207fd2b19b3SKyle Evans return OnOff(color.highlight("V") .. 208aedd6be5SKyle Evans "erbose :", core.verbose) 209088b4f5fSWarner Losh end, 210a51f9f0cSKyle Evans func = core.setVerbose, 2113cd5547bSKyle Evans alias = {"v", "V"}, 212088b4f5fSWarner Losh }, 213d8757746SKyle Evans }, 214aedd6be5SKyle Evans} 215088b4f5fSWarner Losh 216088b4f5fSWarner Loshmenu.welcome = { 217303253e5SKyle Evans entries = function() 218aedd6be5SKyle Evans local menu_entries = menu.welcome.all_entries 219303253e5SKyle Evans -- Swap the first two menu items on single user boot 2209f71d421SKyle Evans if core.isSingleUserBoot() then 2219a0904b0SKyle Evans -- We'll cache the swapped menu, for performance 2229f71d421SKyle Evans if menu.welcome.swapped_menu ~= nil then 223aedd6be5SKyle Evans return menu.welcome.swapped_menu 2249a0904b0SKyle Evans end 2255c1b5165SKyle Evans -- Shallow copy the table 226ee4e69f1SKyle Evans menu_entries = core.deepCopyTable(menu_entries) 2275c1b5165SKyle Evans 2289a0904b0SKyle Evans -- Swap the first two menu entries 2294b6da14cSKyle Evans menu_entries[1], menu_entries[2] = 230aedd6be5SKyle Evans menu_entries[2], menu_entries[1] 231303253e5SKyle Evans 2329a0904b0SKyle Evans -- Then set their names to their alternate names 2339a0904b0SKyle Evans menu_entries[1].name, menu_entries[2].name = 2349a0904b0SKyle Evans menu_entries[1].alternate_name, 235aedd6be5SKyle Evans menu_entries[2].alternate_name 236aedd6be5SKyle Evans menu.welcome.swapped_menu = menu_entries 237303253e5SKyle Evans end 238aedd6be5SKyle Evans return menu_entries 239303253e5SKyle Evans end, 240303253e5SKyle Evans all_entries = { 241088b4f5fSWarner Losh -- boot multi user 242088b4f5fSWarner Losh { 243a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 244a51f9f0cSKyle Evans name = color.highlight("B") .. "oot Multi user " .. 245a51f9f0cSKyle Evans color.highlight("[Enter]"), 2465c1b5165SKyle Evans -- Not a standard menu entry function! 247a51f9f0cSKyle Evans alternate_name = color.highlight("B") .. 248a51f9f0cSKyle Evans "oot Multi user", 249088b4f5fSWarner Losh func = function() 250aedd6be5SKyle Evans core.setSingleUser(false) 251aedd6be5SKyle Evans core.boot() 252088b4f5fSWarner Losh end, 2533cd5547bSKyle Evans alias = {"b", "B"}, 254088b4f5fSWarner Losh }, 255088b4f5fSWarner Losh -- boot single user 256088b4f5fSWarner Losh { 257a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 258a51f9f0cSKyle Evans name = "Boot " .. color.highlight("S") .. "ingle user", 2595c1b5165SKyle Evans -- Not a standard menu entry function! 260a51f9f0cSKyle Evans alternate_name = "Boot " .. color.highlight("S") .. 261a51f9f0cSKyle Evans "ingle user " .. color.highlight("[Enter]"), 262088b4f5fSWarner Losh func = function() 263aedd6be5SKyle Evans core.setSingleUser(true) 264aedd6be5SKyle Evans core.boot() 265088b4f5fSWarner Losh end, 2663cd5547bSKyle Evans alias = {"s", "S"}, 267088b4f5fSWarner Losh }, 268088b4f5fSWarner Losh -- escape to interpreter 269088b4f5fSWarner Losh { 270a7cf0562SKyle Evans entry_type = core.MENU_RETURN, 271a51f9f0cSKyle Evans name = color.highlight("Esc") .. "ape to loader prompt", 272ef625845SKyle Evans func = function() 273aedd6be5SKyle Evans loader.setenv("autoboot_delay", "NO") 274ef625845SKyle Evans end, 2753cd5547bSKyle Evans alias = {core.KEYSTR_ESCAPE}, 276088b4f5fSWarner Losh }, 277088b4f5fSWarner Losh -- reboot 278088b4f5fSWarner Losh { 279a7cf0562SKyle Evans entry_type = core.MENU_ENTRY, 280a51f9f0cSKyle Evans name = color.highlight("R") .. "eboot", 281088b4f5fSWarner Losh func = function() 282aedd6be5SKyle Evans loader.perform("reboot") 283088b4f5fSWarner Losh end, 2843cd5547bSKyle Evans alias = {"r", "R"}, 285088b4f5fSWarner Losh }, 286088b4f5fSWarner Losh { 287a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 288088b4f5fSWarner Losh }, 289088b4f5fSWarner Losh { 290a7cf0562SKyle Evans entry_type = core.MENU_SEPARATOR, 291a51f9f0cSKyle Evans name = "Options:", 292088b4f5fSWarner Losh }, 293088b4f5fSWarner Losh -- kernel options 294088b4f5fSWarner Losh { 295a7cf0562SKyle Evans entry_type = core.MENU_CAROUSEL_ENTRY, 296ada26c4aSKyle Evans carousel_id = "kernel", 297ada26c4aSKyle Evans items = core.kernelList, 298ada26c4aSKyle Evans name = function(idx, choice, all_choices) 2999f71d421SKyle Evans if #all_choices == 0 then 300aedd6be5SKyle Evans return "Kernel: " 301088b4f5fSWarner Losh end 302b1b1f2b8SKyle Evans 303aedd6be5SKyle Evans local is_default = (idx == 1) 304aedd6be5SKyle Evans local kernel_name = "" 305aedd6be5SKyle Evans local name_color 3069f71d421SKyle Evans if is_default then 307aedd6be5SKyle Evans name_color = color.escapef(color.GREEN) 308aedd6be5SKyle Evans kernel_name = "default/" 309bcf48a15SKyle Evans else 310aedd6be5SKyle Evans name_color = color.escapef(color.BLUE) 311b1b1f2b8SKyle Evans end 312fd2b19b3SKyle Evans kernel_name = kernel_name .. name_color .. 313aedd6be5SKyle Evans choice .. color.default() 314fd2b19b3SKyle Evans return color.highlight("K") .. "ernel: " .. 315fd2b19b3SKyle Evans kernel_name .. " (" .. idx .. " of " .. 316aedd6be5SKyle Evans #all_choices .. ")" 317088b4f5fSWarner Losh end, 318e2df27e3SKyle Evans func = function(_, choice, _) 319322a2dddSKyle Evans config.selectKernel(choice) 320088b4f5fSWarner Losh end, 3213cd5547bSKyle Evans alias = {"k", "K"}, 322088b4f5fSWarner Losh }, 323088b4f5fSWarner Losh -- boot options 324088b4f5fSWarner Losh { 325a7cf0562SKyle Evans entry_type = core.MENU_SUBMENU, 326a51f9f0cSKyle Evans name = "Boot " .. color.highlight("O") .. "ptions", 3279a28f948SKyle Evans submenu = menu.boot_options, 3283cd5547bSKyle Evans alias = {"o", "O"}, 329d8757746SKyle Evans }, 3307efc058fSKyle Evans -- boot environments 3317efc058fSKyle Evans { 3327efc058fSKyle Evans entry_type = core.MENU_SUBMENU, 3337efc058fSKyle Evans visible = function() 3347efc058fSKyle Evans return core.isZFSBoot() and 3357efc058fSKyle Evans #core.bootenvList() > 1 3367efc058fSKyle Evans end, 3377efc058fSKyle Evans name = "Boot " .. color.highlight("E") .. "nvironments", 3387efc058fSKyle Evans submenu = menu.boot_environments, 3397efc058fSKyle Evans alias = {"e", "E"}, 3407efc058fSKyle Evans }, 341d8757746SKyle Evans }, 342aedd6be5SKyle Evans} 343088b4f5fSWarner Losh 34420a81676SKyle Evansmenu.default = menu.welcome 34528384160SKyle Evans-- current_alias_table will be used to keep our alias table consistent across 34628384160SKyle Evans-- screen redraws, instead of relying on whatever triggered the redraw to update 34728384160SKyle Evans-- the local alias_table in menu.process. 34828384160SKyle Evansmenu.current_alias_table = {} 34920a81676SKyle Evans 3502a11b810SKyle Evansfunction menu.draw(menudef) 351beafe961SKyle Evans -- Clear the screen, reset the cursor, then draw 352aedd6be5SKyle Evans screen.clear() 353aedd6be5SKyle Evans screen.defcursor() 3542a11b810SKyle Evans menu.current_alias_table = drawer.drawscreen(menudef) 3552a11b810SKyle Evans drawn_menu = menudef 35628384160SKyle Evansend 35728384160SKyle Evans 358ca16d83fSKyle Evans-- 'keypress' allows the caller to indicate that a key has been pressed that we 359ca16d83fSKyle Evans-- should process as our initial input. 3602a11b810SKyle Evansfunction menu.process(menudef, keypress) 3612a11b810SKyle Evans assert(menudef ~= nil) 36228384160SKyle Evans 3632a11b810SKyle Evans if drawn_menu ~= menudef then 3642a11b810SKyle Evans menu.draw(menudef) 3657dcffa90SKyle Evans end 366ca16d83fSKyle Evans 367da9ab827SKyle Evans while true do 368ca16d83fSKyle Evans local key = keypress or io.getchar() 369ca16d83fSKyle Evans keypress = nil 370088b4f5fSWarner Losh 371b458bf0dSKyle Evans -- Special key behaviors 3729f71d421SKyle Evans if (key == core.KEY_BACKSPACE or key == core.KEY_DELETE) and 3732a11b810SKyle Evans menudef ~= menu.default then 374aedd6be5SKyle Evans break 3759f71d421SKyle Evans elseif key == core.KEY_ENTER then 376aedd6be5SKyle Evans core.boot() 377b458bf0dSKyle Evans -- Should not return 378abc4f7e7SKyle Evans end 379abc4f7e7SKyle Evans 380abc4f7e7SKyle Evans key = string.char(key) 381088b4f5fSWarner Losh -- check to see if key is an alias 382aedd6be5SKyle Evans local sel_entry = nil 38328384160SKyle Evans for k, v in pairs(menu.current_alias_table) do 3849f71d421SKyle Evans if key == k then 385aedd6be5SKyle Evans sel_entry = v 38628384160SKyle Evans break 387088b4f5fSWarner Losh end 388088b4f5fSWarner Losh end 389088b4f5fSWarner Losh 390088b4f5fSWarner Losh -- if we have an alias do the assigned action: 3919f71d421SKyle Evans if sel_entry ~= nil then 392aedd6be5SKyle Evans local handler = menu.handlers[sel_entry.entry_type] 3932a11b810SKyle Evans assert(handler ~= nil) 394da9ab827SKyle Evans -- The handler's return value indicates if we 395da9ab827SKyle Evans -- need to exit this menu. An omitted or true 396da9ab827SKyle Evans -- return value means to continue. 3972a11b810SKyle Evans if handler(menudef, sel_entry) == false then 398da9ab827SKyle Evans return 399aefcaa7eSKyle Evans end 40028384160SKyle Evans -- If we got an alias key the screen is out of date... 40128384160SKyle Evans -- redraw it. 4022a11b810SKyle Evans menu.draw(menudef) 403088b4f5fSWarner Losh end 404088b4f5fSWarner Losh end 405088b4f5fSWarner Loshend 406088b4f5fSWarner Losh 407da9ab827SKyle Evansfunction menu.run() 408da9ab827SKyle Evans if menu.skip() then 409da9ab827SKyle Evans core.autoboot() 410da9ab827SKyle Evans return 411da9ab827SKyle Evans end 412da9ab827SKyle Evans 413beafe961SKyle Evans menu.draw(menu.default) 414ca16d83fSKyle Evans local autoboot_key = menu.autoboot() 415ca16d83fSKyle Evans 416ca16d83fSKyle Evans menu.process(menu.default, autoboot_key) 417beafe961SKyle Evans drawn_menu = nil 418da9ab827SKyle Evans 419da9ab827SKyle Evans screen.defcursor() 420da9ab827SKyle Evans print("Exiting menu!") 421088b4f5fSWarner Loshend 422088b4f5fSWarner Losh 423088b4f5fSWarner Loshfunction menu.skip() 4249f71d421SKyle Evans if core.isSerialBoot() then 425aedd6be5SKyle Evans return true 426088b4f5fSWarner Losh end 427aedd6be5SKyle Evans local c = string.lower(loader.getenv("console") or "") 4289f71d421SKyle Evans if c:match("^efi[ ;]") ~= nil or c:match("[ ;]efi[ ;]") ~= nil then 429aedd6be5SKyle Evans return true 430088b4f5fSWarner Losh end 431088b4f5fSWarner Losh 432aedd6be5SKyle Evans c = string.lower(loader.getenv("beastie_disable") or "") 433aedd6be5SKyle Evans print("beastie_disable", c) 434aedd6be5SKyle Evans return c == "yes" 435088b4f5fSWarner Loshend 436088b4f5fSWarner Losh 437088b4f5fSWarner Loshfunction menu.autoboot() 438aedd6be5SKyle Evans local ab = loader.getenv("autoboot_delay") 4399f71d421SKyle Evans if ab ~= nil and ab:lower() == "no" then 44012b95c84SKyle Evans return nil 4419f71d421SKyle Evans elseif tonumber(ab) == -1 then 442aedd6be5SKyle Evans core.boot() 443088b4f5fSWarner Losh end 444aedd6be5SKyle Evans ab = tonumber(ab) or 10 445088b4f5fSWarner Losh 446aedd6be5SKyle Evans local x = loader.getenv("loader_menu_timeout_x") or 5 447aedd6be5SKyle Evans local y = loader.getenv("loader_menu_timeout_y") or 22 448088b4f5fSWarner Losh 449aedd6be5SKyle Evans local endtime = loader.time() + ab 450aedd6be5SKyle Evans local time 451088b4f5fSWarner Losh 452088b4f5fSWarner Losh repeat 453aedd6be5SKyle Evans time = endtime - loader.time() 454aedd6be5SKyle Evans screen.setcursor(x, y) 45557099121SKyle Evans print("Autoboot in " .. time .. 45657099121SKyle Evans " seconds, hit [Enter] to boot" .. 457aedd6be5SKyle Evans " or any other key to stop ") 458aedd6be5SKyle Evans screen.defcursor() 4599f71d421SKyle Evans if io.ischar() then 460aedd6be5SKyle Evans local ch = io.getchar() 4619f71d421SKyle Evans if ch == core.KEY_ENTER then 462aedd6be5SKyle Evans break 463088b4f5fSWarner Losh else 464088b4f5fSWarner Losh -- erase autoboot msg 465aedd6be5SKyle Evans screen.setcursor(0, y) 46666964bbcSKyle Evans print(string.rep(" ", 80)) 467aedd6be5SKyle Evans screen.defcursor() 46812b95c84SKyle Evans return ch 469088b4f5fSWarner Losh end 470088b4f5fSWarner Losh end 471088b4f5fSWarner Losh 472aedd6be5SKyle Evans loader.delay(50000) 473aedd6be5SKyle Evans until time <= 0 474aedd6be5SKyle Evans core.boot() 475088b4f5fSWarner Losh 476088b4f5fSWarner Loshend 477088b4f5fSWarner Losh 478aedd6be5SKyle Evansreturn menu 479