xref: /freebsd/stand/lua/menu.lua (revision aedd6be5c7c3096828fafa6c1528f3966b9e3aa5)
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
31*aedd6be5SKyle Evanslocal core = require("core")
32*aedd6be5SKyle Evanslocal color = require("color")
33*aedd6be5SKyle Evanslocal config = require("config")
34*aedd6be5SKyle Evanslocal screen = require("screen")
35*aedd6be5SKyle Evanslocal drawer = require("drawer")
36088b4f5fSWarner Losh
37*aedd6be5SKyle Evanslocal menu = {}
38c8518398SKyle Evans
39*aedd6be5SKyle Evanslocal skip
40*aedd6be5SKyle Evanslocal run
41*aedd6be5SKyle Evanslocal autoboot
42088b4f5fSWarner Losh
43e15abd1fSKyle Evanslocal OnOff = function(str, b)
44e15abd1fSKyle Evans	if (b) then
45e15abd1fSKyle Evans		return str .. color.escapef(color.GREEN) .. "On" ..
46*aedd6be5SKyle Evans		    color.escapef(color.WHITE)
47e15abd1fSKyle Evans	else
48e15abd1fSKyle Evans		return str .. color.escapef(color.RED) .. "off" ..
49*aedd6be5SKyle Evans		    color.escapef(color.WHITE)
50e15abd1fSKyle Evans	end
51e15abd1fSKyle Evansend
52e15abd1fSKyle Evans
53b5746545SKyle Evans-- Module exports
548d415029SKyle Evansmenu.handlers = {
558d415029SKyle Evans	-- Menu handlers take the current menu and selected entry as parameters,
568d415029SKyle Evans	-- and should return a boolean indicating whether execution should
578d415029SKyle Evans	-- continue or not. The return value may be omitted if this entry should
588d415029SKyle Evans	-- have no bearing on whether we continue or not, indicating that we
598d415029SKyle Evans	-- should just continue after execution.
608d415029SKyle Evans	[core.MENU_ENTRY] = function(current_menu, entry)
618d415029SKyle Evans		-- run function
62*aedd6be5SKyle Evans		entry.func()
638d415029SKyle Evans	end,
648d415029SKyle Evans	[core.MENU_CAROUSEL_ENTRY] = function(current_menu, entry)
658d415029SKyle Evans		-- carousel (rotating) functionality
66*aedd6be5SKyle Evans		local carid = entry.carousel_id
67*aedd6be5SKyle Evans		local caridx = config.getCarouselIndex(carid)
68*aedd6be5SKyle Evans		local choices = entry.items()
698d415029SKyle Evans
708d415029SKyle Evans		if (#choices > 0) then
71*aedd6be5SKyle Evans			caridx = (caridx % #choices) + 1
72*aedd6be5SKyle Evans			config.setCarouselIndex(carid, caridx)
73*aedd6be5SKyle Evans			entry.func(caridx, choices[caridx], choices)
748d415029SKyle Evans		end
758d415029SKyle Evans	end,
768d415029SKyle Evans	[core.MENU_SUBMENU] = function(current_menu, entry)
778d415029SKyle Evans		-- recurse
78*aedd6be5SKyle Evans		return menu.run(entry.submenu())
798d415029SKyle Evans	end,
808d415029SKyle Evans	[core.MENU_RETURN] = function(current_menu, entry)
818d415029SKyle Evans		-- allow entry to have a function/side effect
828d415029SKyle Evans		if (entry.func ~= nil) then
83*aedd6be5SKyle Evans			entry.func()
848d415029SKyle Evans		end
85*aedd6be5SKyle Evans		return false
868d415029SKyle Evans	end,
87*aedd6be5SKyle Evans}
88280e990bSKyle Evans-- loader menu tree is rooted at menu.welcome
89088b4f5fSWarner Losh
90088b4f5fSWarner Loshmenu.boot_options = {
91d8757746SKyle Evans	entries = {
92088b4f5fSWarner Losh		-- return to welcome menu
93088b4f5fSWarner Losh		{
94a7cf0562SKyle Evans			entry_type = core.MENU_RETURN,
95088b4f5fSWarner Losh			name = function()
9657099121SKyle Evans				return "Back to main menu" ..
97*aedd6be5SKyle Evans				    color.highlight(" [Backspace]")
981666dfc0SKyle Evans			end
99088b4f5fSWarner Losh		},
100088b4f5fSWarner Losh
101088b4f5fSWarner Losh		-- load defaults
102088b4f5fSWarner Losh		{
103a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
104088b4f5fSWarner Losh			name = function()
10557099121SKyle Evans				return "Load System " .. color.highlight("D") ..
106*aedd6be5SKyle Evans				    "efaults"
107088b4f5fSWarner Losh			end,
108088b4f5fSWarner Losh			func = function()
109*aedd6be5SKyle Evans				core.setDefaults()
110088b4f5fSWarner Losh			end,
111088b4f5fSWarner Losh			alias = {"d", "D"}
112088b4f5fSWarner Losh		},
113088b4f5fSWarner Losh
114088b4f5fSWarner Losh		{
115a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
116088b4f5fSWarner Losh			name = function()
117*aedd6be5SKyle Evans				return ""
118088b4f5fSWarner Losh			end
119088b4f5fSWarner Losh		},
120088b4f5fSWarner Losh
121088b4f5fSWarner Losh		{
122a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
123088b4f5fSWarner Losh			name = function()
124*aedd6be5SKyle Evans				return "Boot Options:"
125088b4f5fSWarner Losh			end
126088b4f5fSWarner Losh		},
127088b4f5fSWarner Losh
128088b4f5fSWarner Losh		-- acpi
129088b4f5fSWarner Losh		{
130a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
131c1ab36f5SKyle Evans			visible = core.isSystem386,
132088b4f5fSWarner Losh			name = function()
133fd2b19b3SKyle Evans				return OnOff(color.highlight("A") ..
134*aedd6be5SKyle Evans				    "CPI       :", core.acpi)
135088b4f5fSWarner Losh			end,
136088b4f5fSWarner Losh			func = function()
137*aedd6be5SKyle Evans				core.setACPI()
138088b4f5fSWarner Losh			end,
139088b4f5fSWarner Losh			alias = {"a", "A"}
140088b4f5fSWarner Losh		},
141088b4f5fSWarner Losh		-- safe mode
142088b4f5fSWarner Losh		{
143a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
144088b4f5fSWarner Losh			name = function()
14557099121SKyle Evans				return OnOff("Safe " .. color.highlight("M") ..
146*aedd6be5SKyle Evans				    "ode  :", core.sm)
147088b4f5fSWarner Losh			end,
148088b4f5fSWarner Losh			func = function()
149*aedd6be5SKyle Evans				core.setSafeMode()
150088b4f5fSWarner Losh			end,
151088b4f5fSWarner Losh			alias = {"m", "M"}
152088b4f5fSWarner Losh		},
153088b4f5fSWarner Losh		-- single user
154088b4f5fSWarner Losh		{
155a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
156088b4f5fSWarner Losh			name = function()
157fd2b19b3SKyle Evans				return OnOff(color.highlight("S") ..
158*aedd6be5SKyle Evans				    "ingle user:", core.su)
159088b4f5fSWarner Losh			end,
160088b4f5fSWarner Losh			func = function()
161*aedd6be5SKyle Evans				core.setSingleUser()
162088b4f5fSWarner Losh			end,
163088b4f5fSWarner Losh			alias = {"s", "S"}
164088b4f5fSWarner Losh		},
165088b4f5fSWarner Losh		-- verbose boot
166088b4f5fSWarner Losh		{
167a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
168088b4f5fSWarner Losh			name = function()
169fd2b19b3SKyle Evans				return OnOff(color.highlight("V") ..
170*aedd6be5SKyle Evans				    "erbose    :", core.verbose)
171088b4f5fSWarner Losh			end,
172088b4f5fSWarner Losh			func = function()
173*aedd6be5SKyle Evans				core.setVerbose()
174088b4f5fSWarner Losh			end,
175088b4f5fSWarner Losh			alias = {"v", "V"}
176088b4f5fSWarner Losh		},
177d8757746SKyle Evans	},
178*aedd6be5SKyle Evans}
179088b4f5fSWarner Losh
180088b4f5fSWarner Loshmenu.welcome = {
181303253e5SKyle Evans	entries = function()
182*aedd6be5SKyle Evans		local menu_entries = menu.welcome.all_entries
183303253e5SKyle Evans		-- Swap the first two menu items on single user boot
184303253e5SKyle Evans		if (core.isSingleUserBoot()) then
1859a0904b0SKyle Evans			-- We'll cache the swapped menu, for performance
1869a0904b0SKyle Evans			if (menu.welcome.swapped_menu ~= nil) then
187*aedd6be5SKyle Evans				return menu.welcome.swapped_menu
1889a0904b0SKyle Evans			end
1895c1b5165SKyle Evans			-- Shallow copy the table
190*aedd6be5SKyle Evans			menu_entries = core.shallowCopyTable(menu_entries)
1915c1b5165SKyle Evans
1929a0904b0SKyle Evans			-- Swap the first two menu entries
1934b6da14cSKyle Evans			menu_entries[1], menu_entries[2] =
194*aedd6be5SKyle Evans			    menu_entries[2], menu_entries[1]
195303253e5SKyle Evans
1969a0904b0SKyle Evans			-- Then set their names to their alternate names
1979a0904b0SKyle Evans			menu_entries[1].name, menu_entries[2].name =
1989a0904b0SKyle Evans			    menu_entries[1].alternate_name,
199*aedd6be5SKyle Evans			    menu_entries[2].alternate_name
200*aedd6be5SKyle Evans			menu.welcome.swapped_menu = menu_entries
201303253e5SKyle Evans		end
202*aedd6be5SKyle Evans		return menu_entries
203303253e5SKyle Evans	end,
204303253e5SKyle Evans	all_entries = {
205088b4f5fSWarner Losh		-- boot multi user
206088b4f5fSWarner Losh		{
207a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
208088b4f5fSWarner Losh			name = function()
209fd2b19b3SKyle Evans				return color.highlight("B") ..
210fd2b19b3SKyle Evans				    "oot Multi user " ..
211*aedd6be5SKyle Evans				    color.highlight("[Enter]")
212088b4f5fSWarner Losh			end,
2135c1b5165SKyle Evans			-- Not a standard menu entry function!
2145c1b5165SKyle Evans			alternate_name = function()
2155c1b5165SKyle Evans				return color.highlight("B") ..
216*aedd6be5SKyle Evans				    "oot Multi user"
2175c1b5165SKyle Evans			end,
218088b4f5fSWarner Losh			func = function()
219*aedd6be5SKyle Evans				core.setSingleUser(false)
220*aedd6be5SKyle Evans				core.boot()
221088b4f5fSWarner Losh			end,
222b458bf0dSKyle Evans			alias = {"b", "B"}
223088b4f5fSWarner Losh		},
224088b4f5fSWarner Losh
225088b4f5fSWarner Losh		-- boot single user
226088b4f5fSWarner Losh		{
227a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
228088b4f5fSWarner Losh			name = function()
229fd2b19b3SKyle Evans				return "Boot " .. color.highlight("S") ..
230*aedd6be5SKyle Evans				    "ingle user"
231088b4f5fSWarner Losh			end,
2325c1b5165SKyle Evans			-- Not a standard menu entry function!
2335c1b5165SKyle Evans			alternate_name = function()
2345c1b5165SKyle Evans				return "Boot " .. color.highlight("S") ..
235*aedd6be5SKyle Evans				    "ingle user " .. color.highlight("[Enter]")
2365c1b5165SKyle Evans			end,
237088b4f5fSWarner Losh			func = function()
238*aedd6be5SKyle Evans				core.setSingleUser(true)
239*aedd6be5SKyle Evans				core.boot()
240088b4f5fSWarner Losh			end,
241088b4f5fSWarner Losh			alias = {"s", "S"}
242088b4f5fSWarner Losh		},
243088b4f5fSWarner Losh
244088b4f5fSWarner Losh		-- escape to interpreter
245088b4f5fSWarner Losh		{
246a7cf0562SKyle Evans			entry_type = core.MENU_RETURN,
247088b4f5fSWarner Losh			name = function()
248fd2b19b3SKyle Evans				return color.highlight("Esc") ..
249*aedd6be5SKyle Evans				    "ape to loader prompt"
250088b4f5fSWarner Losh			end,
251ef625845SKyle Evans			func = function()
252*aedd6be5SKyle Evans				loader.setenv("autoboot_delay", "NO")
253ef625845SKyle Evans			end,
25439006570SKyle Evans			alias = {core.KEYSTR_ESCAPE}
255088b4f5fSWarner Losh		},
256088b4f5fSWarner Losh
257088b4f5fSWarner Losh		-- reboot
258088b4f5fSWarner Losh		{
259a7cf0562SKyle Evans			entry_type = core.MENU_ENTRY,
260088b4f5fSWarner Losh			name = function()
261*aedd6be5SKyle Evans				return color.highlight("R") .. "eboot"
262088b4f5fSWarner Losh			end,
263088b4f5fSWarner Losh			func = function()
264*aedd6be5SKyle Evans				loader.perform("reboot")
265088b4f5fSWarner Losh			end,
266088b4f5fSWarner Losh			alias = {"r", "R"}
267088b4f5fSWarner Losh		},
268088b4f5fSWarner Losh
269088b4f5fSWarner Losh
270088b4f5fSWarner Losh		{
271a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
272088b4f5fSWarner Losh			name = function()
273*aedd6be5SKyle Evans				return ""
274088b4f5fSWarner Losh			end
275088b4f5fSWarner Losh		},
276088b4f5fSWarner Losh
277088b4f5fSWarner Losh		{
278a7cf0562SKyle Evans			entry_type = core.MENU_SEPARATOR,
279088b4f5fSWarner Losh			name = function()
280*aedd6be5SKyle Evans				return "Options:"
281088b4f5fSWarner Losh			end
282088b4f5fSWarner Losh		},
283088b4f5fSWarner Losh
284088b4f5fSWarner Losh		-- kernel options
285088b4f5fSWarner Losh		{
286a7cf0562SKyle Evans			entry_type = core.MENU_CAROUSEL_ENTRY,
287ada26c4aSKyle Evans			carousel_id = "kernel",
288ada26c4aSKyle Evans			items = core.kernelList,
289ada26c4aSKyle Evans			name = function(idx, choice, all_choices)
29024a1bd54SKyle Evans				if (#all_choices == 0) then
291*aedd6be5SKyle Evans					return "Kernel: "
292088b4f5fSWarner Losh				end
293b1b1f2b8SKyle Evans
294*aedd6be5SKyle Evans				local is_default = (idx == 1)
295*aedd6be5SKyle Evans				local kernel_name = ""
296*aedd6be5SKyle Evans				local name_color
29724a1bd54SKyle Evans				if (is_default) then
298*aedd6be5SKyle Evans					name_color = color.escapef(color.GREEN)
299*aedd6be5SKyle Evans					kernel_name = "default/"
300bcf48a15SKyle Evans				else
301*aedd6be5SKyle Evans					name_color = color.escapef(color.BLUE)
302b1b1f2b8SKyle Evans				end
303fd2b19b3SKyle Evans				kernel_name = kernel_name .. name_color ..
304*aedd6be5SKyle Evans				    choice .. color.default()
305fd2b19b3SKyle Evans				return color.highlight("K") .. "ernel: " ..
306fd2b19b3SKyle Evans				    kernel_name .. " (" .. idx .. " of " ..
307*aedd6be5SKyle Evans				    #all_choices .. ")"
308088b4f5fSWarner Losh			end,
3095d1e2f83SKyle Evans			func = function(idx, choice, all_choices)
310*aedd6be5SKyle Evans				config.selectkernel(choice)
311088b4f5fSWarner Losh			end,
312088b4f5fSWarner Losh			alias = {"k", "K"}
313088b4f5fSWarner Losh		},
314088b4f5fSWarner Losh
315088b4f5fSWarner Losh		-- boot options
316088b4f5fSWarner Losh		{
317a7cf0562SKyle Evans			entry_type = core.MENU_SUBMENU,
318088b4f5fSWarner Losh			name = function()
319fd2b19b3SKyle Evans				return "Boot " .. color.highlight("O") ..
320*aedd6be5SKyle Evans				    "ptions"
321088b4f5fSWarner Losh			end,
322088b4f5fSWarner Losh			submenu = function()
323*aedd6be5SKyle Evans				return menu.boot_options
324088b4f5fSWarner Losh			end,
325088b4f5fSWarner Losh			alias = {"o", "O"}
326d8757746SKyle Evans		},
327d8757746SKyle Evans	},
328*aedd6be5SKyle Evans}
329088b4f5fSWarner Losh
330088b4f5fSWarner Loshfunction menu.run(m)
331088b4f5fSWarner Losh
332088b4f5fSWarner Losh	if (menu.skip()) then
333*aedd6be5SKyle Evans		core.autoboot()
334*aedd6be5SKyle Evans		return false
335088b4f5fSWarner Losh	end
336088b4f5fSWarner Losh
337088b4f5fSWarner Losh	if (m == nil) then
338*aedd6be5SKyle Evans		m = menu.welcome
339088b4f5fSWarner Losh	end
340088b4f5fSWarner Losh
341088b4f5fSWarner Losh	-- redraw screen
342*aedd6be5SKyle Evans	screen.clear()
343*aedd6be5SKyle Evans	screen.defcursor()
344*aedd6be5SKyle Evans	local alias_table = drawer.drawscreen(m)
345088b4f5fSWarner Losh
346*aedd6be5SKyle Evans	menu.autoboot()
347088b4f5fSWarner Losh
348*aedd6be5SKyle Evans	cont = true
34924a1bd54SKyle Evans	while (cont) do
350*aedd6be5SKyle Evans		local key = io.getchar()
351088b4f5fSWarner Losh
352b458bf0dSKyle Evans		-- Special key behaviors
3531504bce3SKyle Evans		if ((key == core.KEY_BACKSPACE) or (key == core.KEY_DELETE)) and
3541504bce3SKyle Evans		    (m ~= menu.welcome) then
355*aedd6be5SKyle Evans			break
356fe672a15SKyle Evans		elseif (key == core.KEY_ENTER) then
357*aedd6be5SKyle Evans			core.boot()
358b458bf0dSKyle Evans			-- Should not return
359abc4f7e7SKyle Evans		end
360abc4f7e7SKyle Evans
361abc4f7e7SKyle Evans		key = string.char(key)
362088b4f5fSWarner Losh		-- check to see if key is an alias
363*aedd6be5SKyle Evans		local sel_entry = nil
364088b4f5fSWarner Losh		for k, v in pairs(alias_table) do
365088b4f5fSWarner Losh			if (key == k) then
366*aedd6be5SKyle Evans				sel_entry = v
367088b4f5fSWarner Losh			end
368088b4f5fSWarner Losh		end
369088b4f5fSWarner Losh
370088b4f5fSWarner Losh		-- if we have an alias do the assigned action:
371088b4f5fSWarner Losh		if (sel_entry ~= nil) then
3728d415029SKyle Evans			-- Get menu handler
373*aedd6be5SKyle Evans			local handler = menu.handlers[sel_entry.entry_type]
3748d415029SKyle Evans			if (handler ~= nil) then
3758d415029SKyle Evans				-- The handler's return value indicates whether
3768d415029SKyle Evans				-- we need to exit this menu. An omitted return
3778d415029SKyle Evans				-- value means "continue" by default.
378*aedd6be5SKyle Evans				cont = handler(m, sel_entry)
3798d415029SKyle Evans				if (cont == nil) then
380*aedd6be5SKyle Evans					cont = true
381aefcaa7eSKyle Evans				end
382088b4f5fSWarner Losh			end
383088b4f5fSWarner Losh			-- if we got an alias key the screen is out of date:
384*aedd6be5SKyle Evans			screen.clear()
385*aedd6be5SKyle Evans			screen.defcursor()
386*aedd6be5SKyle Evans			alias_table = drawer.drawscreen(m)
387088b4f5fSWarner Losh		end
388088b4f5fSWarner Losh	end
389088b4f5fSWarner Losh
390088b4f5fSWarner Losh	if (m == menu.welcome) then
391*aedd6be5SKyle Evans		screen.defcursor()
392*aedd6be5SKyle Evans		print("Exiting menu!")
393*aedd6be5SKyle Evans		return false
394088b4f5fSWarner Losh	end
395088b4f5fSWarner Losh
396*aedd6be5SKyle Evans	return true
397088b4f5fSWarner Loshend
398088b4f5fSWarner Losh
399088b4f5fSWarner Loshfunction menu.skip()
400b140d14bSKyle Evans	if (core.isSerialBoot()) then
401*aedd6be5SKyle Evans		return true
402088b4f5fSWarner Losh	end
403*aedd6be5SKyle Evans	local c = string.lower(loader.getenv("console") or "")
40424a1bd54SKyle Evans	if ((c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil) then
405*aedd6be5SKyle Evans		return true
406088b4f5fSWarner Losh	end
407088b4f5fSWarner Losh
408*aedd6be5SKyle Evans	c = string.lower(loader.getenv("beastie_disable") or "")
409*aedd6be5SKyle Evans	print("beastie_disable", c)
410*aedd6be5SKyle Evans	return c == "yes"
411088b4f5fSWarner Loshend
412088b4f5fSWarner Losh
413088b4f5fSWarner Loshfunction menu.autoboot()
41424a1bd54SKyle Evans	if (menu.already_autoboot == true) then
415*aedd6be5SKyle Evans		return
416088b4f5fSWarner Losh	end
417*aedd6be5SKyle Evans	menu.already_autoboot = true
418088b4f5fSWarner Losh
419*aedd6be5SKyle Evans	local ab = loader.getenv("autoboot_delay")
420702b460dSKyle Evans	if (ab ~= nil) and (ab:lower() == "no") then
421*aedd6be5SKyle Evans		return
422702b460dSKyle Evans	elseif (tonumber(ab) == -1) then
423*aedd6be5SKyle Evans		core.boot()
424088b4f5fSWarner Losh	end
425*aedd6be5SKyle Evans	ab = tonumber(ab) or 10
426088b4f5fSWarner Losh
427*aedd6be5SKyle Evans	local x = loader.getenv("loader_menu_timeout_x") or 5
428*aedd6be5SKyle Evans	local y = loader.getenv("loader_menu_timeout_y") or 22
429088b4f5fSWarner Losh
430*aedd6be5SKyle Evans	local endtime = loader.time() + ab
431*aedd6be5SKyle Evans	local time
432088b4f5fSWarner Losh
433088b4f5fSWarner Losh	repeat
434*aedd6be5SKyle Evans		time = endtime - loader.time()
435*aedd6be5SKyle Evans		screen.setcursor(x, y)
43657099121SKyle Evans		print("Autoboot in " .. time ..
43757099121SKyle Evans		    " seconds, hit [Enter] to boot" ..
438*aedd6be5SKyle Evans		    " or any other key to stop     ")
439*aedd6be5SKyle Evans		screen.defcursor()
44024a1bd54SKyle Evans		if (io.ischar()) then
441*aedd6be5SKyle Evans			local ch = io.getchar()
44224a1bd54SKyle Evans			if (ch == core.KEY_ENTER) then
443*aedd6be5SKyle Evans				break
444088b4f5fSWarner Losh			else
445088b4f5fSWarner Losh				-- erase autoboot msg
446*aedd6be5SKyle Evans				screen.setcursor(0, y)
447088b4f5fSWarner Losh				print("                                        "
448*aedd6be5SKyle Evans				    .. "                                        ")
449*aedd6be5SKyle Evans				screen.defcursor()
450*aedd6be5SKyle Evans				return
451088b4f5fSWarner Losh			end
452088b4f5fSWarner Losh		end
453088b4f5fSWarner Losh
454*aedd6be5SKyle Evans		loader.delay(50000)
455*aedd6be5SKyle Evans	until time <= 0
456*aedd6be5SKyle Evans	core.boot()
457088b4f5fSWarner Losh
458088b4f5fSWarner Loshend
459088b4f5fSWarner Losh
460*aedd6be5SKyle Evansreturn menu
461