xref: /titanic_51/usr/src/boot/sys/boot/forth/beadm.4th (revision a281b0ef076f3b6cd24864ecb984a4b92dd8b1b8)
14a5d661aSToomas Soome\
24a5d661aSToomas Soome\ This file and its contents are supplied under the terms of the
34a5d661aSToomas Soome\ Common Development and Distribution License ("CDDL"), version 1.0.
44a5d661aSToomas Soome\ You may only use this file in accordance with the terms of version
54a5d661aSToomas Soome\ 1.0 of the CDDL.
64a5d661aSToomas Soome\
74a5d661aSToomas Soome\ A full copy of the text of the CDDL should have accompanied this
84a5d661aSToomas Soome\ source.  A copy of the CDDL is also available via the Internet at
94a5d661aSToomas Soome\ http://www.illumos.org/license/CDDL.
104a5d661aSToomas Soome
11*a281b0efSToomas Soome\ Copyright 2017 Toomas Soome <tsoome@me.com>
124a5d661aSToomas Soome
134a5d661aSToomas Soome\ This module is implementing the beadm user command to support listing
144a5d661aSToomas Soome\ and switching Boot Environments (BE) from command line and
154a5d661aSToomas Soome\ support words to provide data for BE menu in loader menu system.
164a5d661aSToomas Soome\ Note: this module needs an update to provide proper BE vocabulary.
174a5d661aSToomas Soome
184a5d661aSToomas Soomeonly forth also support-functions also file-processing
194a5d661aSToomas Soomealso file-processing definitions also parser
204a5d661aSToomas Soomealso line-reading definitions also builtins definitions
214a5d661aSToomas Soome
224a5d661aSToomas Soomevariable page_count
234a5d661aSToomas Soomevariable page_remainder
244a5d661aSToomas Soome0 page_count !
254a5d661aSToomas Soome0 page_remainder !
264a5d661aSToomas Soome
274a5d661aSToomas Soome\ from menu.4th
284a5d661aSToomas Soome: +c! ( N C-ADDR/U K -- C-ADDR/U )
294a5d661aSToomas Soome	3 pick 3 pick	( n c-addr/u k -- n c-addr/u k n c-addr )
304a5d661aSToomas Soome	rot + c!	( n c-addr/u k n c-addr -- n c-addr/u )
314a5d661aSToomas Soome	rot drop	( n c-addr/u -- c-addr/u )
324a5d661aSToomas Soome;
334a5d661aSToomas Soome
344a5d661aSToomas Soome: get_value ( -- )
354a5d661aSToomas Soome	eat_space
364a5d661aSToomas Soome	line_pointer
374a5d661aSToomas Soome	skip_to_end_of_line
384a5d661aSToomas Soome	line_pointer over -
394a5d661aSToomas Soome	strdup value_buffer strset
404a5d661aSToomas Soome	['] exit to parsing_function
414a5d661aSToomas Soome;
424a5d661aSToomas Soome
434a5d661aSToomas Soome: get_name ( -- )
444a5d661aSToomas Soome	read_name
454a5d661aSToomas Soome	['] get_value to parsing_function
464a5d661aSToomas Soome;
474a5d661aSToomas Soome
484a5d661aSToomas Soome: get_name_value
494a5d661aSToomas Soome	line_buffer strget + to end_of_line
504a5d661aSToomas Soome	line_buffer .addr @ to line_pointer
514a5d661aSToomas Soome	['] get_name to parsing_function
524a5d661aSToomas Soome	begin
534a5d661aSToomas Soome		end_of_line? 0=
544a5d661aSToomas Soome	while
554a5d661aSToomas Soome		parsing_function execute
564a5d661aSToomas Soome	repeat
574a5d661aSToomas Soome;
584a5d661aSToomas Soome
594a5d661aSToomas Soome\ beadm support
604a5d661aSToomas Soome: beadm_longest_title ( addr len -- width )
614a5d661aSToomas Soome	0 to end_of_file?
624a5d661aSToomas Soome	O_RDONLY fopen fd !
634a5d661aSToomas Soome	reset_line_reading
644a5d661aSToomas Soome	fd @ -1 = if EOPEN throw then
654a5d661aSToomas Soome	0 >r		\ length into return stack
664a5d661aSToomas Soome	begin
674a5d661aSToomas Soome		end_of_file? 0=
684a5d661aSToomas Soome	while
694a5d661aSToomas Soome		free_buffers
704a5d661aSToomas Soome		read_line
714a5d661aSToomas Soome		get_name_value
724a5d661aSToomas Soome		value_buffer .len @ r@ > if r> drop value_buffer .len @ >r then
734a5d661aSToomas Soome		free_buffers
744a5d661aSToomas Soome		read_line
754a5d661aSToomas Soome	repeat
764a5d661aSToomas Soome	fd @ fclose
774a5d661aSToomas Soome	r> 1 +		\ space between columns
784a5d661aSToomas Soome;
794a5d661aSToomas Soome
804a5d661aSToomas Soome\ Pretty print BE list
814a5d661aSToomas Soome: beadm_list ( width addr len -- )
824a5d661aSToomas Soome	0 to end_of_file?
834a5d661aSToomas Soome	O_RDONLY fopen fd !
844a5d661aSToomas Soome	reset_line_reading
854a5d661aSToomas Soome	fd @ -1 = if EOPEN throw then
86*a281b0efSToomas Soome	." BE" dup 2 - spaces ." Type    Device" cr
874a5d661aSToomas Soome	begin
884a5d661aSToomas Soome		end_of_file? 0=
894a5d661aSToomas Soome	while
904a5d661aSToomas Soome		free_buffers
914a5d661aSToomas Soome		read_line
924a5d661aSToomas Soome		get_name_value
934a5d661aSToomas Soome		value_buffer strget type
944a5d661aSToomas Soome		dup value_buffer .len @ - spaces
954a5d661aSToomas Soome		free_buffers
964a5d661aSToomas Soome		read_line
974a5d661aSToomas Soome		get_name_value
98*a281b0efSToomas Soome		name_buffer strget type
99*a281b0efSToomas Soome		name_buffer strget s" bootfs" compare 0= if 2 spaces then
100*a281b0efSToomas Soome		name_buffer strget s" chain" compare 0= if 3 spaces then
1014a5d661aSToomas Soome		value_buffer strget type cr
1024a5d661aSToomas Soome		free_buffers
1034a5d661aSToomas Soome	repeat
1044a5d661aSToomas Soome	fd @ fclose
1054a5d661aSToomas Soome	drop
1064a5d661aSToomas Soome;
1074a5d661aSToomas Soome
108*a281b0efSToomas Soome\ we are called with strings be_name menu_file, to simplify the stack
109*a281b0efSToomas Soome\ management, we open the menu and free the menu_file.
110*a281b0efSToomas Soome: beadm_bootfs ( be_addr be_len maddr mlen -- addr len taddr tlen flag | flag )
1114a5d661aSToomas Soome	0 to end_of_file?
112*a281b0efSToomas Soome	2dup O_RDONLY fopen fd !
113*a281b0efSToomas Soome	drop free-memory
1144a5d661aSToomas Soome	fd @ -1 = if EOPEN throw then
115*a281b0efSToomas Soome	reset_line_reading
1164a5d661aSToomas Soome	begin
1174a5d661aSToomas Soome		end_of_file? 0=
1184a5d661aSToomas Soome	while
1194a5d661aSToomas Soome		free_buffers
1204a5d661aSToomas Soome		read_line
1214a5d661aSToomas Soome		get_name_value
1224a5d661aSToomas Soome		2dup value_buffer strget compare
1234a5d661aSToomas Soome		0= if ( title == be )
124*a281b0efSToomas Soome			2drop		\ drop be_name
1254a5d661aSToomas Soome			free_buffers
1264a5d661aSToomas Soome			read_line
1274a5d661aSToomas Soome			get_name_value
128*a281b0efSToomas Soome			value_buffer strget strdup
129*a281b0efSToomas Soome			name_buffer strget strdup -1
1304a5d661aSToomas Soome			free_buffers
1314a5d661aSToomas Soome			1 to end_of_file? \ mark end of file to skip the rest
1324a5d661aSToomas Soome		else
1334a5d661aSToomas Soome			read_line	\ skip over next line
1344a5d661aSToomas Soome		then
1354a5d661aSToomas Soome	repeat
1364a5d661aSToomas Soome	fd @ fclose
1374a5d661aSToomas Soome	line_buffer strfree
1384a5d661aSToomas Soome	read_buffer strfree
139*a281b0efSToomas Soome	dup -1 > if ( be_addr be_len )
1404a5d661aSToomas Soome		2drop
141*a281b0efSToomas Soome		0
1424a5d661aSToomas Soome	then
1434a5d661aSToomas Soome;
1444a5d661aSToomas Soome
1454a5d661aSToomas Soome: current-dev ( -- addr len ) \ return current dev
1464a5d661aSToomas Soome	s" currdev" getenv
1474a5d661aSToomas Soome	2dup [char] / strchr nip
1484a5d661aSToomas Soome	dup 0> if ( strchr '/' != NULL ) - else drop then
1494a5d661aSToomas Soome	\ we have now zfs:pool or diskname:
1504a5d661aSToomas Soome;
1514a5d661aSToomas Soome
1524a5d661aSToomas Soome\ chop trailing ':'
1534a5d661aSToomas Soome: colon- ( addr len -- addr len - 1 | addr len )
1544a5d661aSToomas Soome	2dup 1 - + C@ [char] : = if ( string[len-1] == ':' ) 1 - then
1554a5d661aSToomas Soome;
1564a5d661aSToomas Soome
1574a5d661aSToomas Soome\ add trailing ':'
1584a5d661aSToomas Soome: colon+ ( addr len -- addr len+1 )
1594a5d661aSToomas Soome	2dup +			\ addr len -- addr+len
1604a5d661aSToomas Soome	[char] : swap c!	\ save ':' at the end of the string
1614a5d661aSToomas Soome	1+			\ addr len -- addr len+1
1624a5d661aSToomas Soome;
1634a5d661aSToomas Soome
1644a5d661aSToomas Soome\ make menu.lst path
1654a5d661aSToomas Soome: menu.lst ( addr len -- addr' len' )
1664a5d661aSToomas Soome	colon-
1674a5d661aSToomas Soome	\ need to allocate space for len + 16
1684a5d661aSToomas Soome	dup 16 + allocate if ENOMEM throw then
1694a5d661aSToomas Soome	swap 2dup 2>R	\ copy of new addr len to return stack
1704a5d661aSToomas Soome	move 2R>
1714a5d661aSToomas Soome	s" :/boot/menu.lst" strcat
1724a5d661aSToomas Soome;
1734a5d661aSToomas Soome
1744a5d661aSToomas Soome\ list be's on device
1754a5d661aSToomas Soome: list-dev ( addr len -- )
1764a5d661aSToomas Soome	menu.lst 2dup 2>R
1774a5d661aSToomas Soome	beadm_longest_title
1784a5d661aSToomas Soome	line_buffer strfree
1794a5d661aSToomas Soome	read_buffer strfree
1804a5d661aSToomas Soome	R@ swap 2R>	\ addr width addr len
1814a5d661aSToomas Soome	beadm_list free-memory
1824a5d661aSToomas Soome	." Current boot device: " s" currdev" getenv type cr
1834a5d661aSToomas Soome	line_buffer strfree
1844a5d661aSToomas Soome	read_buffer strfree
1854a5d661aSToomas Soome;
1864a5d661aSToomas Soome
1874a5d661aSToomas Soome\ activate be on device.
188*a281b0efSToomas Soome\ if be name was not given, set currdev
189*a281b0efSToomas Soome\ otherwize, we query device:/boot/menu.lst for bootfs and
190*a281b0efSToomas Soome\ if found, and bootfs type is chain, attempt chainload.
191*a281b0efSToomas Soome\ set currdev to bootfs.
192*a281b0efSToomas Soome\ if we were able to set currdev, reload the config
1934a5d661aSToomas Soome
1944a5d661aSToomas Soome: activate-dev ( dev.addr dev.len be.addr be.len -- )
195*a281b0efSToomas Soome
196*a281b0efSToomas Soome	dup 0= if
197*a281b0efSToomas Soome		2drop
198*a281b0efSToomas Soome		colon-			\ remove : at the end of the dev name
1994a5d661aSToomas Soome		dup 1+ allocate if ENOMEM throw then
2004a5d661aSToomas Soome		dup 2swap 0 -rot strcat
2014a5d661aSToomas Soome		colon+
2024a5d661aSToomas Soome		s" currdev" setenv	\ setenv currdev = device
2034a5d661aSToomas Soome		free-memory
2044a5d661aSToomas Soome	else
205*a281b0efSToomas Soome		2swap menu.lst
206*a281b0efSToomas Soome		beadm_bootfs if ( addr len taddr tlen )
207*a281b0efSToomas Soome			2dup s" chain" compare 0= if
208*a281b0efSToomas Soome				drop free-memory	\ free type
209*a281b0efSToomas Soome				2dup
210*a281b0efSToomas Soome				dup 6 + allocate if ENOMEM throw then
211*a281b0efSToomas Soome				dup >R
212*a281b0efSToomas Soome				0 s" chain " strcat
213*a281b0efSToomas Soome				2swap strcat ['] evaluate catch drop
214*a281b0efSToomas Soome				\ We are still there?
215*a281b0efSToomas Soome				R> free-memory		\ free chain command
216*a281b0efSToomas Soome				drop free-memory	\ free addr
217*a281b0efSToomas Soome				exit
218*a281b0efSToomas Soome			then
219*a281b0efSToomas Soome			drop free-memory		\ free type
220*a281b0efSToomas Soome			2dup [char] : strchr nip 0= if
22158c9f557SToomas Soome				\ have dataset and need to get zfs:pool/ROOT/be:
2224a5d661aSToomas Soome				dup 5 + allocate if ENOMEM throw then
2234a5d661aSToomas Soome				0 s" zfs:" strcat
2244a5d661aSToomas Soome				2swap strcat
2254a5d661aSToomas Soome				colon+
226*a281b0efSToomas Soome			then
2274a5d661aSToomas Soome			2dup s" currdev" setenv
2284a5d661aSToomas Soome			drop free-memory
2294a5d661aSToomas Soome		else
230*a281b0efSToomas Soome			." No such BE in menu.lst or menu.lst is missing." cr
231*a281b0efSToomas Soome			exit
2324a5d661aSToomas Soome		then
2334a5d661aSToomas Soome	then
2344a5d661aSToomas Soome
235*a281b0efSToomas Soome	\ reset BE menu
236*a281b0efSToomas Soome	0 page_count !
2374a5d661aSToomas Soome	\ need to do:
2384a5d661aSToomas Soome	0 unload drop
2394a5d661aSToomas Soome	free-module-options
24058c9f557SToomas Soome	\ unset the env variables with kernel arguments
24158c9f557SToomas Soome	s" acpi-user-options" unsetenv
24258c9f557SToomas Soome	s" boot-args" unsetenv
24358c9f557SToomas Soome	s" boot_ask" unsetenv
24458c9f557SToomas Soome	s" boot_single" unsetenv
24558c9f557SToomas Soome	s" boot_verbose" unsetenv
24658c9f557SToomas Soome	s" boot_kmdb" unsetenv
24758c9f557SToomas Soome	s" boot_debug" unsetenv
24858c9f557SToomas Soome	s" boot_reconfigure" unsetenv
2494a5d661aSToomas Soome	start			\ load config, kernel and modules
2504a5d661aSToomas Soome	." Current boot device: " s" currdev" getenv type cr
2514a5d661aSToomas Soome;
2524a5d661aSToomas Soome
2534a5d661aSToomas Soome\ beadm list [device]
254*a281b0efSToomas Soome\ beadm activate BE [device] | device
2554a5d661aSToomas Soome\
2564a5d661aSToomas Soome\ lists BE's from current or specified device /boot/menu.lst file
2574a5d661aSToomas Soome\ activates specified BE by unloading modules, setting currdev and
2584a5d661aSToomas Soome\ running start to load configuration.
2594a5d661aSToomas Soome: beadm ( -- ) ( throws: abort )
2604a5d661aSToomas Soome	0= if ( interpreted ) get_arguments then
2614a5d661aSToomas Soome
2624a5d661aSToomas Soome	dup 0= if
2634a5d661aSToomas Soome		." Usage:" cr
264*a281b0efSToomas Soome		." beadm activate {beName [device] | device}" cr
2654a5d661aSToomas Soome		." beadm list [device]" cr
2664a5d661aSToomas Soome		." Use lsdev to get device names." cr
2674a5d661aSToomas Soome		drop exit
2684a5d661aSToomas Soome	then
2694a5d661aSToomas Soome	\ First argument is 0 when we're interprated.  See support.4th
2704a5d661aSToomas Soome	\ for get_arguments reading the rest of the line and parsing it
2714a5d661aSToomas Soome	\ stack: argN lenN ... arg1 len1 N
2724a5d661aSToomas Soome	\ rotate arg1 len1, dont use argv[] as we want to get arg1 out of stack
2734a5d661aSToomas Soome	-rot 2dup
2744a5d661aSToomas Soome
2754a5d661aSToomas Soome	s" list" compare-insensitive 0= if ( list )
2764a5d661aSToomas Soome		2drop
2774a5d661aSToomas Soome		argc 1 = if ( list currdev )
2784a5d661aSToomas Soome			\ add dev to list of args and switch to case 2
2794a5d661aSToomas Soome			current-dev rot 1 +
2804a5d661aSToomas Soome		then
2814a5d661aSToomas Soome		2 = if ( list device ) list-dev exit then
2824a5d661aSToomas Soome		." too many arguments" cr abort
2834a5d661aSToomas Soome	then
2844a5d661aSToomas Soome	s" activate" compare-insensitive 0= if ( activate )
2854a5d661aSToomas Soome		argc 1 = if ( missing be )
2864a5d661aSToomas Soome			drop ." missing bName" cr abort
2874a5d661aSToomas Soome		then
2884a5d661aSToomas Soome		argc 2 = if ( activate be )
2894a5d661aSToomas Soome			\ need to set arg list into proper order
2904a5d661aSToomas Soome			1+ >R	\ save argc+1 to return stack
2914a5d661aSToomas Soome				\ if we have : in name, its device, inject
292*a281b0efSToomas Soome				\ empty be name
2934a5d661aSToomas Soome			2dup [char] : strchr nip
2944a5d661aSToomas Soome			if ( its : in name )
295*a281b0efSToomas Soome				0 0 R>
2964a5d661aSToomas Soome			else
2974a5d661aSToomas Soome				\ add device, swap with be and receive argc
2984a5d661aSToomas Soome				current-dev 2swap R>
2994a5d661aSToomas Soome			then
3004a5d661aSToomas Soome		then
3014a5d661aSToomas Soome		3 = if ( activate be device ) activate-dev exit then
3024a5d661aSToomas Soome		." too many arguments" cr abort
3034a5d661aSToomas Soome	then
3044a5d661aSToomas Soome	." Unknown argument" cr abort
3054a5d661aSToomas Soome;
3064a5d661aSToomas Soome
3074a5d661aSToomas Soomealso forth definitions also builtins
3084a5d661aSToomas Soome
3094a5d661aSToomas Soome\ make beadm available as user command.
3104a5d661aSToomas Soomebuiltin: beadm
3114a5d661aSToomas Soome
3124a5d661aSToomas Soome\ count the pages of BE list
3134a5d661aSToomas Soome\ leave FALSE in stack in case of error
3144a5d661aSToomas Soome: be-pages ( -- flag )
3154a5d661aSToomas Soome	1 local flag
3164a5d661aSToomas Soome	0 0 2local currdev
3174a5d661aSToomas Soome	0 0 2local title
3184a5d661aSToomas Soome	end-locals
3194a5d661aSToomas Soome
3204a5d661aSToomas Soome	current-dev menu.lst 2dup 2>R
3214a5d661aSToomas Soome	0 to end_of_file?
3224a5d661aSToomas Soome	O_RDONLY fopen fd !
3234a5d661aSToomas Soome	2R> drop free-memory
3244a5d661aSToomas Soome	reset_line_reading
3254a5d661aSToomas Soome	fd @ -1 = if FALSE else
3264a5d661aSToomas Soome		s" currdev" getenv
3274a5d661aSToomas Soome		over			( addr len addr )
3284a5d661aSToomas Soome		4 s" zfs:" compare 0= if
3294a5d661aSToomas Soome			5 -			\ len -= 5
3304a5d661aSToomas Soome			swap 4 +		\ addr += 4
3314a5d661aSToomas Soome			swap to currdev
3324a5d661aSToomas Soome		then
3334a5d661aSToomas Soome
3344a5d661aSToomas Soome		0
3354a5d661aSToomas Soome		begin
3364a5d661aSToomas Soome			end_of_file? 0=
3374a5d661aSToomas Soome		while
3384a5d661aSToomas Soome			read_line
3394a5d661aSToomas Soome			get_name_value
3404a5d661aSToomas Soome			s" title" name_buffer strget compare
3414a5d661aSToomas Soome			0= if 1+ then
3424a5d661aSToomas Soome
3434a5d661aSToomas Soome			flag if		\ check for title
3444a5d661aSToomas Soome				value_buffer strget strdup to title free_buffers
3454a5d661aSToomas Soome				read_line		\ get bootfs
3464a5d661aSToomas Soome				get_name_value
3474a5d661aSToomas Soome				value_buffer strget currdev compare 0= if
3484a5d661aSToomas Soome					title s" zfs_be_active" setenv
3494a5d661aSToomas Soome					0 to flag
3504a5d661aSToomas Soome				then
3514a5d661aSToomas Soome				title drop free-memory 0 0 to title
3524a5d661aSToomas Soome				free_buffers
3534a5d661aSToomas Soome			else
3544a5d661aSToomas Soome				free_buffers
3554a5d661aSToomas Soome				read_line		\ get bootfs
3564a5d661aSToomas Soome			then
3574a5d661aSToomas Soome		repeat
3584a5d661aSToomas Soome		fd @ fclose
3594a5d661aSToomas Soome		line_buffer strfree
3604a5d661aSToomas Soome		read_buffer strfree
3614a5d661aSToomas Soome		5 /mod swap dup page_remainder !		\ save remainder
3624a5d661aSToomas Soome		if 1+ then
3634a5d661aSToomas Soome		dup page_count !				\ save count
3644a5d661aSToomas Soome		s>d <# #s #> s" zfs_be_pages" setenv
3654a5d661aSToomas Soome		TRUE
3664a5d661aSToomas Soome	then
3674a5d661aSToomas Soome;
3684a5d661aSToomas Soome
369*a281b0efSToomas Soome: be-set-page { | entry count n device -- }
3704a5d661aSToomas Soome	page_count @ 0= if
3714a5d661aSToomas Soome		be-pages
3724a5d661aSToomas Soome		page_count @ 0= if exit then
3734a5d661aSToomas Soome	then
3744a5d661aSToomas Soome
375*a281b0efSToomas Soome	0 to device
3764a5d661aSToomas Soome	s" zfs_be_currpage" getenv dup -1 = if
3774a5d661aSToomas Soome		drop s" 1"
3784a5d661aSToomas Soome	then
3794a5d661aSToomas Soome	0 s>d 2swap
3804a5d661aSToomas Soome	>number ( ud caddr/u -- ud' caddr'/u' )
3814a5d661aSToomas Soome	2drop
3824a5d661aSToomas Soome	1 um/mod nip 5 *
3834a5d661aSToomas Soome	page_count @ 5 *
3844a5d661aSToomas Soome	page_remainder @ if
3854a5d661aSToomas Soome		5 page_remainder @ - -
3864a5d661aSToomas Soome	then
3874a5d661aSToomas Soome	swap -
3884a5d661aSToomas Soome	dup to entry
3894a5d661aSToomas Soome	0 < if
3904a5d661aSToomas Soome		entry 5 + to count
3914a5d661aSToomas Soome		0 to entry
3924a5d661aSToomas Soome	else
3934a5d661aSToomas Soome		5 to count
3944a5d661aSToomas Soome	then
3954a5d661aSToomas Soome	current-dev menu.lst 2dup 2>R
3964a5d661aSToomas Soome	0 to end_of_file?
3974a5d661aSToomas Soome	O_RDONLY fopen fd !
3984a5d661aSToomas Soome	2R> drop free-memory
3994a5d661aSToomas Soome	reset_line_reading
4004a5d661aSToomas Soome	fd @ -1 = if EOPEN throw then
4014a5d661aSToomas Soome	0 to n
4024a5d661aSToomas Soome	begin
4034a5d661aSToomas Soome		end_of_file? 0=
4044a5d661aSToomas Soome	while
4054a5d661aSToomas Soome		n entry < if
4064a5d661aSToomas Soome			read_line		\ skip title
4074a5d661aSToomas Soome			read_line		\ skip bootfs
4084a5d661aSToomas Soome			n 1+ to n
4094a5d661aSToomas Soome		else
4105cbd0311SToomas Soome			\ Use reverse loop to display descending order
41158c9f557SToomas Soome			\ for BE list.
4125cbd0311SToomas Soome			0 count 1- do
4134a5d661aSToomas Soome				read_line		\ read title line
4144a5d661aSToomas Soome				get_name_value
4154a5d661aSToomas Soome				value_buffer strget
4164a5d661aSToomas Soome				52 i +			\ ascii 4 + i
4174a5d661aSToomas Soome				s" bootenvmenu_caption[4]" 20 +c! setenv
4184a5d661aSToomas Soome				value_buffer strget
4194a5d661aSToomas Soome				52 i +			\ ascii 4 + i
4204a5d661aSToomas Soome				s" bootenvansi_caption[4]" 20 +c! setenv
421*a281b0efSToomas Soome
4224a5d661aSToomas Soome				free_buffers
4234a5d661aSToomas Soome				read_line		\ read value line
4244a5d661aSToomas Soome				get_name_value
425*a281b0efSToomas Soome
426*a281b0efSToomas Soome				\ set menu entry command
427*a281b0efSToomas Soome				name_buffer strget s" chain" compare
428*a281b0efSToomas Soome				0= if
429*a281b0efSToomas Soome					s" set_be_chain"
430*a281b0efSToomas Soome				else
431*a281b0efSToomas Soome					s" set_bootenv"
432*a281b0efSToomas Soome				then
4334a5d661aSToomas Soome				52 i +			\ ascii 4 + i
434*a281b0efSToomas Soome				s" bootenvmenu_command[4]" 20 +c! setenv
435*a281b0efSToomas Soome
436*a281b0efSToomas Soome				\ set device name
437*a281b0efSToomas Soome				name_buffer strget s" chain" compare
438*a281b0efSToomas Soome				0= if
439*a281b0efSToomas Soome					\ for chain, use the value as is
440*a281b0efSToomas Soome					value_buffer strget
441*a281b0efSToomas Soome				else
442*a281b0efSToomas Soome					value_buffer strget 2dup
443*a281b0efSToomas Soome					[char] : strchr nip
444*a281b0efSToomas Soome					0= if
445*a281b0efSToomas Soome						\ make zfs device name
446*a281b0efSToomas Soome						swap drop
447*a281b0efSToomas Soome						5 + allocate if
448*a281b0efSToomas Soome							ENOMEM throw
449*a281b0efSToomas Soome						then
450*a281b0efSToomas Soome						s" zfs:" ( addr addr' len' )
451*a281b0efSToomas Soome						2 pick swap move ( addr )
452*a281b0efSToomas Soome						dup to device
453*a281b0efSToomas Soome						4 value_buffer strget
454*a281b0efSToomas Soome						strcat	( addr len )
455*a281b0efSToomas Soome						s" :" strcat
456*a281b0efSToomas Soome					then
457*a281b0efSToomas Soome				then
458*a281b0efSToomas Soome
459*a281b0efSToomas Soome				52 i +			\ ascii 4 + i
4604a5d661aSToomas Soome				s" bootenv_root[4]" 13 +c! setenv
461*a281b0efSToomas Soome				device free-memory 0 to device
4624a5d661aSToomas Soome				free_buffers
4635cbd0311SToomas Soome				-1
4645cbd0311SToomas Soome			+loop
4654a5d661aSToomas Soome
4664a5d661aSToomas Soome			5 count do		\ unset unused entries
4674a5d661aSToomas Soome				52 i +			\ ascii 4 + i
4684a5d661aSToomas Soome				dup s" bootenvmenu_caption[4]" 20 +c! unsetenv
4694a5d661aSToomas Soome				dup s" bootenvansi_caption[4]" 20 +c! unsetenv
4704a5d661aSToomas Soome				dup s" bootenvmenu_command[4]" 20 +c! unsetenv
4714a5d661aSToomas Soome				s" bootenv_root[4]" 13 +c! unsetenv
4724a5d661aSToomas Soome			loop
4734a5d661aSToomas Soome
4744a5d661aSToomas Soome			1 to end_of_file?		\ we are done
4754a5d661aSToomas Soome		then
4764a5d661aSToomas Soome	repeat
4774a5d661aSToomas Soome	fd @ fclose
4784a5d661aSToomas Soome	line_buffer strfree
4794a5d661aSToomas Soome	read_buffer strfree
4804a5d661aSToomas Soome;
481