xref: /freebsd/stand/lua/menu.lua (revision 7efc058f76fa7af45860d864f4f9cd93b2c35de4)
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
39aedd6be5SKyle Evanslocal skip
40aedd6be5SKyle Evanslocal run
41aedd6be5SKyle Evanslocal autoboot
42088b4f5fSWarner Losh
43e15abd1fSKyle Evanslocal OnOff = function(str, b)
449f71d421SKyle Evans	if b 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
53*7efc058fSKyle Evanslocal bootenvSet = function(env)
54*7efc058fSKyle Evans	loader.setenv("vfs.root.mountfrom", env)
55*7efc058fSKyle Evans	loader.setenv("currdev", env .. ":")
56*7efc058fSKyle Evans	config.reload()
57*7efc058fSKyle Evansend
58*7efc058fSKyle 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.
668d415029SKyle Evans	[core.MENU_ENTRY] = function(current_menu, entry)
678d415029SKyle Evans		-- run function
68aedd6be5SKyle Evans		entry.func()
698d415029SKyle Evans	end,
708d415029SKyle Evans	[core.MENU_CAROUSEL_ENTRY] = function(current_menu, 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,
848d415029SKyle Evans	[core.MENU_SUBMENU] = function(current_menu, entry)
858d415029SKyle Evans		-- recurse
869a28f948SKyle Evans		return menu.run(entry.submenu)
878d415029SKyle Evans	end,
888d415029SKyle Evans	[core.MENU_RETURN] = function(current_menu, entry)
898d415029SKyle Evans		-- allow entry to have a function/side effect
909f71d421SKyle Evans		if entry.func ~= nil then
91aedd6be5SKyle Evans			entry.func()
928d415029SKyle Evans		end
93aedd6be5SKyle Evans		return false
948d415029SKyle Evans	end,
95aedd6be5SKyle Evans}
96280e990bSKyle Evans-- loader menu tree is rooted at menu.welcome
97088b4f5fSWarner Losh
98*7efc058fSKyle Evansmenu.boot_environments = {
99*7efc058fSKyle Evans	entries = {
100*7efc058fSKyle Evans		-- return to welcome menu
101*7efc058fSKyle Evans		{
102*7efc058fSKyle Evans			entry_type = core.MENU_RETURN,
103*7efc058fSKyle Evans			name = "Back to main menu" ..
104*7efc058fSKyle Evans			    color.highlight(" [Backspace]"),
105*7efc058fSKyle Evans		},
106*7efc058fSKyle Evans		{
107*7efc058fSKyle Evans			entry_type = core.MENU_CAROUSEL_ENTRY,
108*7efc058fSKyle Evans			carousel_id = "be_active",
109*7efc058fSKyle Evans			items = core.bootenvList,
110*7efc058fSKyle Evans			name = function(idx, choice, all_choices)
111*7efc058fSKyle Evans				if #all_choices == 0 then
112*7efc058fSKyle Evans					return "Active: "
113*7efc058fSKyle Evans				end
114*7efc058fSKyle Evans
115*7efc058fSKyle Evans				local is_default = (idx == 1)
116*7efc058fSKyle Evans				local bootenv_name = ""
117*7efc058fSKyle Evans				local name_color
118*7efc058fSKyle Evans				if is_default then
119*7efc058fSKyle Evans					name_color = color.escapef(color.GREEN)
120*7efc058fSKyle Evans				else
121*7efc058fSKyle Evans					name_color = color.escapef(color.BLUE)
122*7efc058fSKyle Evans				end
123*7efc058fSKyle Evans				bootenv_name = bootenv_name .. name_color ..
124*7efc058fSKyle Evans				    choice .. color.default()
125*7efc058fSKyle Evans				return color.highlight("A").."ctive: " ..
126*7efc058fSKyle Evans				    bootenv_name .. " (" .. idx .. " of " ..
127*7efc058fSKyle Evans				    #all_choices .. ")"
128*7efc058fSKyle Evans			end,
129*7efc058fSKyle Evans			func = function(idx, choice, all_choices)
130*7efc058fSKyle Evans				bootenvSet(choice)
131*7efc058fSKyle Evans			end,
132*7efc058fSKyle Evans			alias = {"a", "A"},
133*7efc058fSKyle Evans		},
134*7efc058fSKyle Evans		{
135*7efc058fSKyle Evans			entry_type = core.MENU_ENTRY,
136*7efc058fSKyle Evans			name = function()
137*7efc058fSKyle Evans				return color.highlight("b") .. "ootfs: " ..
138*7efc058fSKyle Evans				    core.bootenvDefault()
139*7efc058fSKyle Evans			end,
140*7efc058fSKyle Evans			func = function()
141*7efc058fSKyle Evans				-- Reset active boot environment to the default
142*7efc058fSKyle Evans				config.setCarouselIndex("be_active", 1)
143*7efc058fSKyle Evans				bootenvSet(core.bootenvDefault())
144*7efc058fSKyle Evans			end,
145*7efc058fSKyle Evans			alias = {"b", "B"},
146*7efc058fSKyle Evans		},
147*7efc058fSKyle Evans	},
148*7efc058fSKyle Evans}
149*7efc058fSKyle Evans
150088b4f5fSWarner Loshmenu.boot_options = {
151d8757746SKyle Evans	entries = {
152088b4f5fSWarner Losh		-- return to welcome menu
153088b4f5fSWarner Losh		{
154a7cf0562SKyle Evans			entry_type = core.MENU_RETURN,
155a51f9f0cSKyle Evans			name = "Back to main menu" ..
156a51f9f0cSKyle Evans			    color.highlight(" [Backspace]"),
157088b4f5fSWarner Losh		},
158088b4f5fSWarner Losh		-- load defaults
159088b4f5fSWarner Losh		{
160a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
161a51f9f0cSKyle Evans			name = "Load System " .. color.highlight("D") ..
162a51f9f0cSKyle Evans			    "efaults",
163a51f9f0cSKyle Evans			func = core.setDefaults,
164088b4f5fSWarner Losh			alias = {"d", "D"}
165088b4f5fSWarner Losh		},
166088b4f5fSWarner Losh		{
167a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
168088b4f5fSWarner Losh		},
169088b4f5fSWarner Losh		{
170a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
171a51f9f0cSKyle Evans			name = "Boot Options:",
172088b4f5fSWarner Losh		},
173088b4f5fSWarner Losh		-- acpi
174088b4f5fSWarner Losh		{
175a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
176c1ab36f5SKyle Evans			visible = core.isSystem386,
177088b4f5fSWarner Losh			name = function()
178fd2b19b3SKyle Evans				return OnOff(color.highlight("A") ..
179aedd6be5SKyle Evans				    "CPI       :", core.acpi)
180088b4f5fSWarner Losh			end,
181a51f9f0cSKyle Evans			func = core.setACPI,
182088b4f5fSWarner Losh			alias = {"a", "A"}
183088b4f5fSWarner Losh		},
184088b4f5fSWarner Losh		-- safe mode
185088b4f5fSWarner Losh		{
186a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
187088b4f5fSWarner Losh			name = function()
18857099121SKyle Evans				return OnOff("Safe " .. color.highlight("M") ..
189aedd6be5SKyle Evans				    "ode  :", core.sm)
190088b4f5fSWarner Losh			end,
191a51f9f0cSKyle Evans			func = core.setSafeMode,
192088b4f5fSWarner Losh			alias = {"m", "M"}
193088b4f5fSWarner Losh		},
194088b4f5fSWarner Losh		-- single user
195088b4f5fSWarner Losh		{
196a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
197088b4f5fSWarner Losh			name = function()
198fd2b19b3SKyle Evans				return OnOff(color.highlight("S") ..
199aedd6be5SKyle Evans				    "ingle user:", core.su)
200088b4f5fSWarner Losh			end,
201a51f9f0cSKyle Evans			func = core.setSingleUser,
202088b4f5fSWarner Losh			alias = {"s", "S"}
203088b4f5fSWarner Losh		},
204088b4f5fSWarner Losh		-- verbose boot
205088b4f5fSWarner Losh		{
206a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
207088b4f5fSWarner Losh			name = function()
208fd2b19b3SKyle Evans				return OnOff(color.highlight("V") ..
209aedd6be5SKyle Evans				    "erbose    :", core.verbose)
210088b4f5fSWarner Losh			end,
211a51f9f0cSKyle Evans			func = core.setVerbose,
212088b4f5fSWarner Losh			alias = {"v", "V"}
213088b4f5fSWarner Losh		},
214d8757746SKyle Evans	},
215aedd6be5SKyle Evans}
216088b4f5fSWarner Losh
217088b4f5fSWarner Loshmenu.welcome = {
218303253e5SKyle Evans	entries = function()
219aedd6be5SKyle Evans		local menu_entries = menu.welcome.all_entries
220303253e5SKyle Evans		-- Swap the first two menu items on single user boot
2219f71d421SKyle Evans		if core.isSingleUserBoot() then
2229a0904b0SKyle Evans			-- We'll cache the swapped menu, for performance
2239f71d421SKyle Evans			if menu.welcome.swapped_menu ~= nil then
224aedd6be5SKyle Evans				return menu.welcome.swapped_menu
2259a0904b0SKyle Evans			end
2265c1b5165SKyle Evans			-- Shallow copy the table
227aedd6be5SKyle Evans			menu_entries = core.shallowCopyTable(menu_entries)
2285c1b5165SKyle Evans
2299a0904b0SKyle Evans			-- Swap the first two menu entries
2304b6da14cSKyle Evans			menu_entries[1], menu_entries[2] =
231aedd6be5SKyle Evans			    menu_entries[2], menu_entries[1]
232303253e5SKyle Evans
2339a0904b0SKyle Evans			-- Then set their names to their alternate names
2349a0904b0SKyle Evans			menu_entries[1].name, menu_entries[2].name =
2359a0904b0SKyle Evans			    menu_entries[1].alternate_name,
236aedd6be5SKyle Evans			    menu_entries[2].alternate_name
237aedd6be5SKyle Evans			menu.welcome.swapped_menu = menu_entries
238303253e5SKyle Evans		end
239aedd6be5SKyle Evans		return menu_entries
240303253e5SKyle Evans	end,
241303253e5SKyle Evans	all_entries = {
242088b4f5fSWarner Losh		-- boot multi user
243088b4f5fSWarner Losh		{
244a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
245a51f9f0cSKyle Evans			name = color.highlight("B") .. "oot Multi user " ..
246a51f9f0cSKyle Evans			    color.highlight("[Enter]"),
2475c1b5165SKyle Evans			-- Not a standard menu entry function!
248a51f9f0cSKyle Evans			alternate_name = color.highlight("B") ..
249a51f9f0cSKyle Evans			    "oot Multi user",
250088b4f5fSWarner Losh			func = function()
251aedd6be5SKyle Evans				core.setSingleUser(false)
252aedd6be5SKyle Evans				core.boot()
253088b4f5fSWarner Losh			end,
254b458bf0dSKyle Evans			alias = {"b", "B"}
255088b4f5fSWarner Losh		},
256088b4f5fSWarner Losh		-- boot single user
257088b4f5fSWarner Losh		{
258a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
259a51f9f0cSKyle Evans			name = "Boot " .. color.highlight("S") .. "ingle user",
2605c1b5165SKyle Evans			-- Not a standard menu entry function!
261a51f9f0cSKyle Evans			alternate_name = "Boot " .. color.highlight("S") ..
262a51f9f0cSKyle Evans			    "ingle user " .. color.highlight("[Enter]"),
263088b4f5fSWarner Losh			func = function()
264aedd6be5SKyle Evans				core.setSingleUser(true)
265aedd6be5SKyle Evans				core.boot()
266088b4f5fSWarner Losh			end,
267088b4f5fSWarner Losh			alias = {"s", "S"}
268088b4f5fSWarner Losh		},
269088b4f5fSWarner Losh		-- escape to interpreter
270088b4f5fSWarner Losh		{
271a7cf0562SKyle Evans			entry_type = core.MENU_RETURN,
272a51f9f0cSKyle Evans			name = color.highlight("Esc") .. "ape to loader prompt",
273ef625845SKyle Evans			func = function()
274aedd6be5SKyle Evans				loader.setenv("autoboot_delay", "NO")
275ef625845SKyle Evans			end,
27639006570SKyle Evans			alias = {core.KEYSTR_ESCAPE}
277088b4f5fSWarner Losh		},
278088b4f5fSWarner Losh		-- reboot
279088b4f5fSWarner Losh		{
280a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
281a51f9f0cSKyle Evans			name = color.highlight("R") .. "eboot",
282088b4f5fSWarner Losh			func = function()
283aedd6be5SKyle Evans				loader.perform("reboot")
284088b4f5fSWarner Losh			end,
285088b4f5fSWarner Losh			alias = {"r", "R"}
286088b4f5fSWarner Losh		},
287088b4f5fSWarner Losh		{
288a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
289088b4f5fSWarner Losh		},
290088b4f5fSWarner Losh		{
291a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
292a51f9f0cSKyle Evans			name = "Options:",
293088b4f5fSWarner Losh		},
294088b4f5fSWarner Losh		-- kernel options
295088b4f5fSWarner Losh		{
296a7cf0562SKyle Evans			entry_type = core.MENU_CAROUSEL_ENTRY,
297ada26c4aSKyle Evans			carousel_id = "kernel",
298ada26c4aSKyle Evans			items = core.kernelList,
299ada26c4aSKyle Evans			name = function(idx, choice, all_choices)
3009f71d421SKyle Evans				if #all_choices == 0 then
301aedd6be5SKyle Evans					return "Kernel: "
302088b4f5fSWarner Losh				end
303b1b1f2b8SKyle Evans
304aedd6be5SKyle Evans				local is_default = (idx == 1)
305aedd6be5SKyle Evans				local kernel_name = ""
306aedd6be5SKyle Evans				local name_color
3079f71d421SKyle Evans				if is_default then
308aedd6be5SKyle Evans					name_color = color.escapef(color.GREEN)
309aedd6be5SKyle Evans					kernel_name = "default/"
310bcf48a15SKyle Evans				else
311aedd6be5SKyle Evans					name_color = color.escapef(color.BLUE)
312b1b1f2b8SKyle Evans				end
313fd2b19b3SKyle Evans				kernel_name = kernel_name .. name_color ..
314aedd6be5SKyle Evans				    choice .. color.default()
315fd2b19b3SKyle Evans				return color.highlight("K") .. "ernel: " ..
316fd2b19b3SKyle Evans				    kernel_name .. " (" .. idx .. " of " ..
317aedd6be5SKyle Evans				    #all_choices .. ")"
318088b4f5fSWarner Losh			end,
3195d1e2f83SKyle Evans			func = function(idx, choice, all_choices)
320aedd6be5SKyle Evans				config.selectkernel(choice)
321088b4f5fSWarner Losh			end,
322088b4f5fSWarner Losh			alias = {"k", "K"}
323088b4f5fSWarner Losh		},
324088b4f5fSWarner Losh		-- boot options
325088b4f5fSWarner Losh		{
326a7cf0562SKyle Evans			entry_type = core.MENU_SUBMENU,
327a51f9f0cSKyle Evans			name = "Boot " .. color.highlight("O") .. "ptions",
3289a28f948SKyle Evans			submenu = menu.boot_options,
329088b4f5fSWarner Losh			alias = {"o", "O"}
330d8757746SKyle Evans		},
331*7efc058fSKyle Evans		-- boot environments
332*7efc058fSKyle Evans		{
333*7efc058fSKyle Evans			entry_type = core.MENU_SUBMENU,
334*7efc058fSKyle Evans			visible = function()
335*7efc058fSKyle Evans				return core.isZFSBoot() and
336*7efc058fSKyle Evans				    #core.bootenvList() > 1
337*7efc058fSKyle Evans			end,
338*7efc058fSKyle Evans			name = "Boot " .. color.highlight("E") .. "nvironments",
339*7efc058fSKyle Evans			submenu = menu.boot_environments,
340*7efc058fSKyle Evans			alias = {"e", "E"},
341*7efc058fSKyle Evans		},
342d8757746SKyle Evans	},
343aedd6be5SKyle Evans}
344088b4f5fSWarner Losh
34520a81676SKyle Evansmenu.default = menu.welcome
34620a81676SKyle Evans
347088b4f5fSWarner Loshfunction menu.run(m)
348088b4f5fSWarner Losh
3499f71d421SKyle Evans	if menu.skip() then
350aedd6be5SKyle Evans		core.autoboot()
351aedd6be5SKyle Evans		return false
352088b4f5fSWarner Losh	end
353088b4f5fSWarner Losh
3549f71d421SKyle Evans	if m == nil then
35520a81676SKyle Evans		m = menu.default
356088b4f5fSWarner Losh	end
357088b4f5fSWarner Losh
358088b4f5fSWarner Losh	-- redraw screen
359aedd6be5SKyle Evans	screen.clear()
360aedd6be5SKyle Evans	screen.defcursor()
361aedd6be5SKyle Evans	local alias_table = drawer.drawscreen(m)
362088b4f5fSWarner Losh
36312b95c84SKyle Evans	-- Might return nil, that's ok
36412b95c84SKyle Evans	local autoboot_key = menu.autoboot()
365088b4f5fSWarner Losh
366aedd6be5SKyle Evans	cont = true
3679f71d421SKyle Evans	while cont do
36812b95c84SKyle Evans		local key = autoboot_key or io.getchar()
36912b95c84SKyle Evans		autoboot_key = nil
370088b4f5fSWarner Losh
371b458bf0dSKyle Evans		-- Special key behaviors
3729f71d421SKyle Evans		if (key == core.KEY_BACKSPACE or key == core.KEY_DELETE) and
37320a81676SKyle Evans		    m ~= 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
383088b4f5fSWarner Losh		for k, v in pairs(alias_table) do
3849f71d421SKyle Evans			if key == k then
385aedd6be5SKyle Evans				sel_entry = v
386088b4f5fSWarner Losh			end
387088b4f5fSWarner Losh		end
388088b4f5fSWarner Losh
389088b4f5fSWarner Losh		-- if we have an alias do the assigned action:
3909f71d421SKyle Evans		if sel_entry ~= nil then
3918d415029SKyle Evans			-- Get menu handler
392aedd6be5SKyle Evans			local handler = menu.handlers[sel_entry.entry_type]
3939f71d421SKyle Evans			if handler ~= nil then
3948d415029SKyle Evans				-- The handler's return value indicates whether
3958d415029SKyle Evans				-- we need to exit this menu. An omitted return
3968d415029SKyle Evans				-- value means "continue" by default.
397aedd6be5SKyle Evans				cont = handler(m, sel_entry)
3989f71d421SKyle Evans				if cont == nil then
399aedd6be5SKyle Evans					cont = true
400aefcaa7eSKyle Evans				end
401088b4f5fSWarner Losh			end
402088b4f5fSWarner Losh			-- if we got an alias key the screen is out of date:
403aedd6be5SKyle Evans			screen.clear()
404aedd6be5SKyle Evans			screen.defcursor()
405aedd6be5SKyle Evans			alias_table = drawer.drawscreen(m)
406088b4f5fSWarner Losh		end
407088b4f5fSWarner Losh	end
408088b4f5fSWarner Losh
40920a81676SKyle Evans	if m == menu.default then
410aedd6be5SKyle Evans		screen.defcursor()
411aedd6be5SKyle Evans		print("Exiting menu!")
412aedd6be5SKyle Evans		return false
413088b4f5fSWarner Losh	end
414088b4f5fSWarner Losh
415aedd6be5SKyle Evans	return true
416088b4f5fSWarner Loshend
417088b4f5fSWarner Losh
418088b4f5fSWarner Loshfunction menu.skip()
4199f71d421SKyle Evans	if core.isSerialBoot() then
420aedd6be5SKyle Evans		return true
421088b4f5fSWarner Losh	end
422aedd6be5SKyle Evans	local c = string.lower(loader.getenv("console") or "")
4239f71d421SKyle Evans	if c:match("^efi[ ;]") ~= nil or c:match("[ ;]efi[ ;]") ~= nil then
424aedd6be5SKyle Evans		return true
425088b4f5fSWarner Losh	end
426088b4f5fSWarner Losh
427aedd6be5SKyle Evans	c = string.lower(loader.getenv("beastie_disable") or "")
428aedd6be5SKyle Evans	print("beastie_disable", c)
429aedd6be5SKyle Evans	return c == "yes"
430088b4f5fSWarner Loshend
431088b4f5fSWarner Losh
432088b4f5fSWarner Loshfunction menu.autoboot()
43349550489SKyle Evans	if menu.already_autoboot then
43412b95c84SKyle Evans		return nil
435088b4f5fSWarner Losh	end
436aedd6be5SKyle Evans	menu.already_autoboot = true
437088b4f5fSWarner Losh
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)
466088b4f5fSWarner Losh				print("                                        "
467aedd6be5SKyle Evans				    .. "                                        ")
468aedd6be5SKyle Evans				screen.defcursor()
46912b95c84SKyle Evans				return ch
470088b4f5fSWarner Losh			end
471088b4f5fSWarner Losh		end
472088b4f5fSWarner Losh
473aedd6be5SKyle Evans		loader.delay(50000)
474aedd6be5SKyle Evans	until time <= 0
475aedd6be5SKyle Evans	core.boot()
476088b4f5fSWarner Losh
477088b4f5fSWarner Loshend
478088b4f5fSWarner Losh
479aedd6be5SKyle Evansreturn menu
480