xref: /illumos-gate/usr/src/boot/forth/beadm.4th (revision 28703145)
1199767f8SToomas Soome\
2199767f8SToomas Soome\ This file and its contents are supplied under the terms of the
3199767f8SToomas Soome\ Common Development and Distribution License ("CDDL"), version 1.0.
4199767f8SToomas Soome\ You may only use this file in accordance with the terms of version
5199767f8SToomas Soome\ 1.0 of the CDDL.
6199767f8SToomas Soome\
7199767f8SToomas Soome\ A full copy of the text of the CDDL should have accompanied this
8199767f8SToomas Soome\ source.  A copy of the CDDL is also available via the Internet at
9199767f8SToomas Soome\ http://www.illumos.org/license/CDDL.
10199767f8SToomas Soome
1111571644SToomas Soome\ Copyright 2017 Toomas Soome <tsoome@me.com>
120ff6ce5fSAndy Fiddaman\ Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
13c3e6a6edSJohn Levon\ Copyright 2019 Joyent, Inc.
14199767f8SToomas Soome
15199767f8SToomas Soome\ This module is implementing the beadm user command to support listing
16199767f8SToomas Soome\ and switching Boot Environments (BE) from command line and
17199767f8SToomas Soome\ support words to provide data for BE menu in loader menu system.
18199767f8SToomas Soome\ Note: this module needs an update to provide proper BE vocabulary.
19199767f8SToomas Soome
20199767f8SToomas Soomeonly forth also support-functions also file-processing
21199767f8SToomas Soomealso file-processing definitions also parser
22199767f8SToomas Soomealso line-reading definitions also builtins definitions
23199767f8SToomas Soome
24199767f8SToomas Soomevariable page_count
25199767f8SToomas Soomevariable page_remainder
26199767f8SToomas Soome0 page_count !
27199767f8SToomas Soome0 page_remainder !
28199767f8SToomas Soome
29199767f8SToomas Soome\ from menu.4th
30199767f8SToomas Soome: +c! ( N C-ADDR/U K -- C-ADDR/U )
31199767f8SToomas Soome	3 pick 3 pick	( n c-addr/u k -- n c-addr/u k n c-addr )
32199767f8SToomas Soome	rot + c!	( n c-addr/u k n c-addr -- n c-addr/u )
33199767f8SToomas Soome	rot drop	( n c-addr/u -- c-addr/u )
34199767f8SToomas Soome;
35199767f8SToomas Soome
36199767f8SToomas Soome: get_value ( -- )
37199767f8SToomas Soome	eat_space
38199767f8SToomas Soome	line_pointer
39199767f8SToomas Soome	skip_to_end_of_line
40199767f8SToomas Soome	line_pointer over -
41199767f8SToomas Soome	strdup value_buffer strset
42199767f8SToomas Soome	['] exit to parsing_function
43199767f8SToomas Soome;
44199767f8SToomas Soome
45199767f8SToomas Soome: get_name ( -- )
46199767f8SToomas Soome	read_name
47199767f8SToomas Soome	['] get_value to parsing_function
48199767f8SToomas Soome;
49199767f8SToomas Soome
50199767f8SToomas Soome: get_name_value
51199767f8SToomas Soome	line_buffer strget + to end_of_line
52199767f8SToomas Soome	line_buffer .addr @ to line_pointer
53199767f8SToomas Soome	['] get_name to parsing_function
54199767f8SToomas Soome	begin
55199767f8SToomas Soome		end_of_line? 0=
56199767f8SToomas Soome	while
57199767f8SToomas Soome		parsing_function execute
58199767f8SToomas Soome	repeat
59199767f8SToomas Soome;
60199767f8SToomas Soome
61199767f8SToomas Soome\ beadm support
62199767f8SToomas Soome: beadm_longest_title ( addr len -- width )
63199767f8SToomas Soome	0 to end_of_file?
64199767f8SToomas Soome	O_RDONLY fopen fd !
65199767f8SToomas Soome	reset_line_reading
66199767f8SToomas Soome	fd @ -1 = if EOPEN throw then
67199767f8SToomas Soome	0 >r		\ length into return stack
68199767f8SToomas Soome	begin
69199767f8SToomas Soome		end_of_file? 0=
70199767f8SToomas Soome	while
71199767f8SToomas Soome		free_buffers
72199767f8SToomas Soome		read_line
73199767f8SToomas Soome		get_name_value
74199767f8SToomas Soome		value_buffer .len @ r@ > if r> drop value_buffer .len @ >r then
75199767f8SToomas Soome		free_buffers
76199767f8SToomas Soome		read_line
77199767f8SToomas Soome	repeat
78199767f8SToomas Soome	fd @ fclose
79199767f8SToomas Soome	r> 1 +		\ space between columns
80199767f8SToomas Soome;
81199767f8SToomas Soome
82199767f8SToomas Soome\ Pretty print BE list
83199767f8SToomas Soome: beadm_list ( width addr len -- )
84199767f8SToomas Soome	0 to end_of_file?
85199767f8SToomas Soome	O_RDONLY fopen fd !
86199767f8SToomas Soome	reset_line_reading
87199767f8SToomas Soome	fd @ -1 = if EOPEN throw then
8811571644SToomas Soome	." BE" dup 2 - spaces ." Type    Device" cr
89199767f8SToomas Soome	begin
90199767f8SToomas Soome		end_of_file? 0=
91199767f8SToomas Soome	while
92199767f8SToomas Soome		free_buffers
93199767f8SToomas Soome		read_line
94199767f8SToomas Soome		get_name_value
95199767f8SToomas Soome		value_buffer strget type
96199767f8SToomas Soome		dup value_buffer .len @ - spaces
97199767f8SToomas Soome		free_buffers
98199767f8SToomas Soome		read_line
99199767f8SToomas Soome		get_name_value
10011571644SToomas Soome		name_buffer strget type
10111571644SToomas Soome		name_buffer strget s" bootfs" compare 0= if 2 spaces then
10211571644SToomas Soome		name_buffer strget s" chain" compare 0= if 3 spaces then
103199767f8SToomas Soome		value_buffer strget type cr
104199767f8SToomas Soome		free_buffers
105199767f8SToomas Soome	repeat
106199767f8SToomas Soome	fd @ fclose
107199767f8SToomas Soome	drop
108199767f8SToomas Soome;
109199767f8SToomas Soome
110*28703145SToomas Soome\ we are called with strings be_name menu_file, to simplify the stack
11111571644SToomas Soome\ management, we open the menu and free the menu_file.
11211571644SToomas Soome: beadm_bootfs ( be_addr be_len maddr mlen -- addr len taddr tlen flag | flag )
113199767f8SToomas Soome	0 to end_of_file?
11411571644SToomas Soome	2dup O_RDONLY fopen fd !
11511571644SToomas Soome	drop free-memory
116199767f8SToomas Soome	fd @ -1 = if EOPEN throw then
11711571644SToomas Soome	reset_line_reading
118199767f8SToomas Soome	begin
119199767f8SToomas Soome		end_of_file? 0=
120199767f8SToomas Soome	while
121199767f8SToomas Soome		free_buffers
122199767f8SToomas Soome		read_line
123199767f8SToomas Soome		get_name_value
124199767f8SToomas Soome		2dup value_buffer strget compare
125199767f8SToomas Soome		0= if ( title == be )
12611571644SToomas Soome			2drop		\ drop be_name
127199767f8SToomas Soome			free_buffers
128199767f8SToomas Soome			read_line
129199767f8SToomas Soome			get_name_value
13011571644SToomas Soome			value_buffer strget strdup
13111571644SToomas Soome			name_buffer strget strdup -1
132199767f8SToomas Soome			free_buffers
133199767f8SToomas Soome			1 to end_of_file? \ mark end of file to skip the rest
134199767f8SToomas Soome		else
135199767f8SToomas Soome			read_line	\ skip over next line
136199767f8SToomas Soome		then
137199767f8SToomas Soome	repeat
138199767f8SToomas Soome	fd @ fclose
139199767f8SToomas Soome	line_buffer strfree
140199767f8SToomas Soome	read_buffer strfree
14111571644SToomas Soome	dup -1 > if ( be_addr be_len )
142199767f8SToomas Soome		2drop
14311571644SToomas Soome		0
144199767f8SToomas Soome	then
145199767f8SToomas Soome;
146199767f8SToomas Soome
147199767f8SToomas Soome: current-dev ( -- addr len ) \ return current dev
148199767f8SToomas Soome	s" currdev" getenv
149199767f8SToomas Soome	2dup [char] / strchr nip
150199767f8SToomas Soome	dup 0> if ( strchr '/' != NULL ) - else drop then
151199767f8SToomas Soome	\ we have now zfs:pool or diskname:
152199767f8SToomas Soome;
153199767f8SToomas Soome
154199767f8SToomas Soome\ chop trailing ':'
155199767f8SToomas Soome: colon- ( addr len -- addr len - 1 | addr len )
156199767f8SToomas Soome	2dup 1 - + C@ [char] : = if ( string[len-1] == ':' ) 1 - then
157199767f8SToomas Soome;
158199767f8SToomas Soome
159199767f8SToomas Soome\ add trailing ':'
160199767f8SToomas Soome: colon+ ( addr len -- addr len+1 )
161199767f8SToomas Soome	2dup +			\ addr len -- addr+len
162199767f8SToomas Soome	[char] : swap c!	\ save ':' at the end of the string
163199767f8SToomas Soome	1+			\ addr len -- addr len+1
164199767f8SToomas Soome;
165199767f8SToomas Soome
166199767f8SToomas Soome\ make menu.lst path
167199767f8SToomas Soome: menu.lst ( addr len -- addr' len' )
168199767f8SToomas Soome	colon-
169199767f8SToomas Soome	\ need to allocate space for len + 16
170199767f8SToomas Soome	dup 16 + allocate if ENOMEM throw then
171199767f8SToomas Soome	swap 2dup 2>R	\ copy of new addr len to return stack
172199767f8SToomas Soome	move 2R>
173199767f8SToomas Soome	s" :/boot/menu.lst" strcat
174199767f8SToomas Soome;
175199767f8SToomas Soome
176199767f8SToomas Soome\ list be's on device
177199767f8SToomas Soome: list-dev ( addr len -- )
178199767f8SToomas Soome	menu.lst 2dup 2>R
179199767f8SToomas Soome	beadm_longest_title
180199767f8SToomas Soome	line_buffer strfree
181199767f8SToomas Soome	read_buffer strfree
182199767f8SToomas Soome	R@ swap 2R>	\ addr width addr len
183199767f8SToomas Soome	beadm_list free-memory
184199767f8SToomas Soome	." Current boot device: " s" currdev" getenv type cr
185199767f8SToomas Soome	line_buffer strfree
186199767f8SToomas Soome	read_buffer strfree
187199767f8SToomas Soome;
188199767f8SToomas Soome
189199767f8SToomas Soome\ activate be on device.
19011571644SToomas Soome\ if be name was not given, set currdev
19111571644SToomas Soome\ otherwize, we query device:/boot/menu.lst for bootfs and
19211571644SToomas Soome\ if found, and bootfs type is chain, attempt chainload.
19311571644SToomas Soome\ set currdev to bootfs.
19411571644SToomas Soome\ if we were able to set currdev, reload the config
195199767f8SToomas Soome
196199767f8SToomas Soome: activate-dev ( dev.addr dev.len be.addr be.len -- )
19711571644SToomas Soome
19811571644SToomas Soome	dup 0= if
19911571644SToomas Soome		2drop
20011571644SToomas Soome		colon-			\ remove : at the end of the dev name
201199767f8SToomas Soome		dup 1+ allocate if ENOMEM throw then
202199767f8SToomas Soome		dup 2swap 0 -rot strcat
203199767f8SToomas Soome		colon+
204199767f8SToomas Soome		s" currdev" setenv	\ setenv currdev = device
205199767f8SToomas Soome		free-memory
206199767f8SToomas Soome	else
20711571644SToomas Soome		2swap menu.lst
20811571644SToomas Soome		beadm_bootfs if ( addr len taddr tlen )
20911571644SToomas Soome			2dup s" chain" compare 0= if
21011571644SToomas Soome				drop free-memory	\ free type
21111571644SToomas Soome				2dup
21211571644SToomas Soome				dup 6 + allocate if ENOMEM throw then
21311571644SToomas Soome				dup >R
21411571644SToomas Soome				0 s" chain " strcat
21511571644SToomas Soome				2swap strcat ['] evaluate catch drop
21611571644SToomas Soome				\ We are still there?
21711571644SToomas Soome				R> free-memory		\ free chain command
21811571644SToomas Soome				drop free-memory	\ free addr
21911571644SToomas Soome				exit
22011571644SToomas Soome			then
22111571644SToomas Soome			drop free-memory		\ free type
2226f01cc52SToomas Soome			\ check last char in the name
2236f01cc52SToomas Soome			2dup + c@ [char] : <> if
2242aa37581SToomas Soome				\ have dataset and need to get zfs:pool/ROOT/be:
22511571644SToomas Soome				dup 5 + allocate if ENOMEM throw then
22611571644SToomas Soome				0 s" zfs:" strcat
22711571644SToomas Soome				2swap strcat
22811571644SToomas Soome				colon+
22911571644SToomas Soome			then
230199767f8SToomas Soome			2dup s" currdev" setenv
231199767f8SToomas Soome			drop free-memory
232199767f8SToomas Soome		else
23311571644SToomas Soome			." No such BE in menu.lst or menu.lst is missing." cr
23411571644SToomas Soome			exit
235199767f8SToomas Soome		then
236199767f8SToomas Soome	then
237199767f8SToomas Soome
23811571644SToomas Soome	\ reset BE menu
23911571644SToomas Soome	0 page_count !
240199767f8SToomas Soome	\ need to do:
241199767f8SToomas Soome	0 unload drop
242199767f8SToomas Soome	free-module-options
2432aa37581SToomas Soome	\ unset the env variables with kernel arguments
2442aa37581SToomas Soome	s" acpi-user-options" unsetenv
2452aa37581SToomas Soome	s" boot-args" unsetenv
2462aa37581SToomas Soome	s" boot_ask" unsetenv
2472aa37581SToomas Soome	s" boot_single" unsetenv
2482aa37581SToomas Soome	s" boot_verbose" unsetenv
2492aa37581SToomas Soome	s" boot_kmdb" unsetenv
250c3e6a6edSJohn Levon	s" boot_drop_into_kmdb" unsetenv
2512aa37581SToomas Soome	s" boot_reconfigure" unsetenv
252519c7dc9SToomas Soome	s" boot_noncluster" unsetenv
253199767f8SToomas Soome	start			\ load config, kernel and modules
254199767f8SToomas Soome	." Current boot device: " s" currdev" getenv type cr
255199767f8SToomas Soome;
256199767f8SToomas Soome
257199767f8SToomas Soome\ beadm list [device]
25811571644SToomas Soome\ beadm activate BE [device] | device
259199767f8SToomas Soome\
260199767f8SToomas Soome\ lists BE's from current or specified device /boot/menu.lst file
261199767f8SToomas Soome\ activates specified BE by unloading modules, setting currdev and
262199767f8SToomas Soome\ running start to load configuration.
263199767f8SToomas Soome: beadm ( -- ) ( throws: abort )
264199767f8SToomas Soome	0= if ( interpreted ) get_arguments then
265199767f8SToomas Soome
266199767f8SToomas Soome	dup 0= if
267199767f8SToomas Soome		." Usage:" cr
26811571644SToomas Soome		." beadm activate {beName [device] | device}" cr
269199767f8SToomas Soome		." beadm list [device]" cr
270199767f8SToomas Soome		." Use lsdev to get device names." cr
271199767f8SToomas Soome		drop exit
272199767f8SToomas Soome	then
273199767f8SToomas Soome	\ First argument is 0 when we're interprated.  See support.4th
274199767f8SToomas Soome	\ for get_arguments reading the rest of the line and parsing it
275199767f8SToomas Soome	\ stack: argN lenN ... arg1 len1 N
276199767f8SToomas Soome	\ rotate arg1 len1, dont use argv[] as we want to get arg1 out of stack
277199767f8SToomas Soome	-rot 2dup
278199767f8SToomas Soome
279199767f8SToomas Soome	s" list" compare-insensitive 0= if ( list )
280199767f8SToomas Soome		2drop
281199767f8SToomas Soome		argc 1 = if ( list currdev )
282199767f8SToomas Soome			\ add dev to list of args and switch to case 2
283199767f8SToomas Soome			current-dev rot 1 +
284199767f8SToomas Soome		then
285199767f8SToomas Soome		2 = if ( list device ) list-dev exit then
286199767f8SToomas Soome		." too many arguments" cr abort
287199767f8SToomas Soome	then
288199767f8SToomas Soome	s" activate" compare-insensitive 0= if ( activate )
289199767f8SToomas Soome		argc 1 = if ( missing be )
290199767f8SToomas Soome			drop ." missing bName" cr abort
291199767f8SToomas Soome		then
292199767f8SToomas Soome		argc 2 = if ( activate be )
293199767f8SToomas Soome			\ need to set arg list into proper order
29411571644SToomas Soome			1+ >R	\ save argc+1 to return stack
2956f01cc52SToomas Soome
2966f01cc52SToomas Soome			\ if the prefix is fd, cd, net or disk and we have :
2976f01cc52SToomas Soome			\ in the name, it is device and inject empty be name
2986f01cc52SToomas Soome			over 2 s" fd" compare 0= >R
2996f01cc52SToomas Soome			over 2 s" cd" compare 0= R> or >R
3006f01cc52SToomas Soome			over 3 s" net" compare 0= R> or >R
3016f01cc52SToomas Soome			over 4 s" disk" compare 0= R> or
3026f01cc52SToomas Soome			if ( prefix is fd or cd or net or disk )
3036f01cc52SToomas Soome				2dup [char] : strchr nip
3046f01cc52SToomas Soome				if ( its : in name )
3056f01cc52SToomas Soome					true
3066f01cc52SToomas Soome				else
3076f01cc52SToomas Soome					false
3086f01cc52SToomas Soome				then
3096f01cc52SToomas Soome			else
3106f01cc52SToomas Soome				false
3116f01cc52SToomas Soome			then
3126f01cc52SToomas Soome
3136f01cc52SToomas Soome			if ( it is device name )
31411571644SToomas Soome				0 0 R>
315199767f8SToomas Soome			else
316199767f8SToomas Soome				\ add device, swap with be and receive argc
317199767f8SToomas Soome				current-dev 2swap R>
318199767f8SToomas Soome			then
319199767f8SToomas Soome		then
320199767f8SToomas Soome		3 = if ( activate be device ) activate-dev exit then
321199767f8SToomas Soome		." too many arguments" cr abort
322199767f8SToomas Soome	then
323199767f8SToomas Soome	." Unknown argument" cr abort
324199767f8SToomas Soome;
325199767f8SToomas Soome
326199767f8SToomas Soomealso forth definitions also builtins
327199767f8SToomas Soome
328199767f8SToomas Soome\ make beadm available as user command.
329199767f8SToomas Soomebuiltin: beadm
330199767f8SToomas Soome
331199767f8SToomas Soome\ count the pages of BE list
332199767f8SToomas Soome\ leave FALSE in stack in case of error
333199767f8SToomas Soome: be-pages ( -- flag )
334199767f8SToomas Soome	1 local flag
335199767f8SToomas Soome	0 0 2local currdev
336199767f8SToomas Soome	0 0 2local title
337199767f8SToomas Soome	end-locals
338199767f8SToomas Soome
339199767f8SToomas Soome	current-dev menu.lst 2dup 2>R
340199767f8SToomas Soome	0 to end_of_file?
341199767f8SToomas Soome	O_RDONLY fopen fd !
342199767f8SToomas Soome	2R> drop free-memory
343199767f8SToomas Soome	reset_line_reading
344199767f8SToomas Soome	fd @ -1 = if FALSE else
345199767f8SToomas Soome		s" currdev" getenv
346199767f8SToomas Soome		over			( addr len addr )
347199767f8SToomas Soome		4 s" zfs:" compare 0= if
348199767f8SToomas Soome			5 -			\ len -= 5
349199767f8SToomas Soome			swap 4 +		\ addr += 4
350199767f8SToomas Soome			swap to currdev
351199767f8SToomas Soome		then
352199767f8SToomas Soome
353199767f8SToomas Soome		0
354199767f8SToomas Soome		begin
355199767f8SToomas Soome			end_of_file? 0=
356199767f8SToomas Soome		while
357199767f8SToomas Soome			read_line
358199767f8SToomas Soome			get_name_value
359199767f8SToomas Soome			s" title" name_buffer strget compare
360199767f8SToomas Soome			0= if 1+ then
361199767f8SToomas Soome
362199767f8SToomas Soome			flag if		\ check for title
363199767f8SToomas Soome				value_buffer strget strdup to title free_buffers
364199767f8SToomas Soome				read_line		\ get bootfs
365199767f8SToomas Soome				get_name_value
366199767f8SToomas Soome				value_buffer strget currdev compare 0= if
367199767f8SToomas Soome					title s" zfs_be_active" setenv
368199767f8SToomas Soome					0 to flag
369199767f8SToomas Soome				then
370199767f8SToomas Soome				title drop free-memory 0 0 to title
371199767f8SToomas Soome				free_buffers
372199767f8SToomas Soome			else
373199767f8SToomas Soome				free_buffers
374199767f8SToomas Soome				read_line		\ get bootfs
375199767f8SToomas Soome			then
376199767f8SToomas Soome		repeat
377199767f8SToomas Soome		fd @ fclose
378199767f8SToomas Soome		line_buffer strfree
379199767f8SToomas Soome		read_buffer strfree
380199767f8SToomas Soome		5 /mod swap dup page_remainder !		\ save remainder
381199767f8SToomas Soome		if 1+ then
382199767f8SToomas Soome		dup page_count !				\ save count
3830ff6ce5fSAndy Fiddaman		n2s s" zfs_be_pages" setenv
384199767f8SToomas Soome		TRUE
385199767f8SToomas Soome	then
386199767f8SToomas Soome;
387199767f8SToomas Soome
38811571644SToomas Soome: be-set-page { | entry count n device -- }
389199767f8SToomas Soome	page_count @ 0= if
390199767f8SToomas Soome		be-pages
391199767f8SToomas Soome		page_count @ 0= if exit then
392199767f8SToomas Soome	then
393199767f8SToomas Soome
39411571644SToomas Soome	0 to device
3950ff6ce5fSAndy Fiddaman	1 s" zfs_be_currpage" getenvn
3960ff6ce5fSAndy Fiddaman	5 *
397199767f8SToomas Soome	page_count @ 5 *
398199767f8SToomas Soome	page_remainder @ if
399199767f8SToomas Soome		5 page_remainder @ - -
400199767f8SToomas Soome	then
401199767f8SToomas Soome	swap -
402199767f8SToomas Soome	dup to entry
403199767f8SToomas Soome	0 < if
404199767f8SToomas Soome		entry 5 + to count
405199767f8SToomas Soome		0 to entry
406199767f8SToomas Soome	else
407199767f8SToomas Soome		5 to count
408199767f8SToomas Soome	then
409199767f8SToomas Soome	current-dev menu.lst 2dup 2>R
410199767f8SToomas Soome	0 to end_of_file?
411199767f8SToomas Soome	O_RDONLY fopen fd !
412199767f8SToomas Soome	2R> drop free-memory
413199767f8SToomas Soome	reset_line_reading
414199767f8SToomas Soome	fd @ -1 = if EOPEN throw then
415199767f8SToomas Soome	0 to n
416199767f8SToomas Soome	begin
417199767f8SToomas Soome		end_of_file? 0=
418199767f8SToomas Soome	while
419199767f8SToomas Soome		n entry < if
420199767f8SToomas Soome			read_line		\ skip title
421199767f8SToomas Soome			read_line		\ skip bootfs
422199767f8SToomas Soome			n 1+ to n
423199767f8SToomas Soome		else
424568506e1SToomas Soome			\ Use reverse loop to display descending order
4252aa37581SToomas Soome			\ for BE list.
426568506e1SToomas Soome			0 count 1- do
427199767f8SToomas Soome				read_line		\ read title line
428199767f8SToomas Soome				get_name_value
429199767f8SToomas Soome				value_buffer strget
430199767f8SToomas Soome				52 i +			\ ascii 4 + i
431199767f8SToomas Soome				s" bootenvmenu_caption[4]" 20 +c! setenv
432199767f8SToomas Soome				value_buffer strget
433199767f8SToomas Soome				52 i +			\ ascii 4 + i
434199767f8SToomas Soome				s" bootenvansi_caption[4]" 20 +c! setenv
43511571644SToomas Soome
436199767f8SToomas Soome				free_buffers
437199767f8SToomas Soome				read_line		\ read value line
438199767f8SToomas Soome				get_name_value
43911571644SToomas Soome
44011571644SToomas Soome				\ set menu entry command
44111571644SToomas Soome				name_buffer strget s" chain" compare
44211571644SToomas Soome				0= if
44311571644SToomas Soome					s" set_be_chain"
44411571644SToomas Soome				else
44511571644SToomas Soome					s" set_bootenv"
44611571644SToomas Soome				then
44711571644SToomas Soome				52 i +			\ ascii 4 + i
44811571644SToomas Soome				s" bootenvmenu_command[4]" 20 +c! setenv
44911571644SToomas Soome
45011571644SToomas Soome				\ set device name
45111571644SToomas Soome				name_buffer strget s" chain" compare
45211571644SToomas Soome				0= if
453*28703145SToomas Soome					\ for chain, use the value as is
45411571644SToomas Soome					value_buffer strget
45511571644SToomas Soome				else
4566f01cc52SToomas Soome					\ check last char in the name
4576f01cc52SToomas Soome					value_buffer strget 2dup + c@
4586f01cc52SToomas Soome					[char] : <> if
45911571644SToomas Soome						\ make zfs device name
46011571644SToomas Soome						swap drop
46111571644SToomas Soome						5 + allocate if
46211571644SToomas Soome							ENOMEM throw
46311571644SToomas Soome						then
46411571644SToomas Soome						s" zfs:" ( addr addr' len' )
46511571644SToomas Soome						2 pick swap move ( addr )
46611571644SToomas Soome						dup to device
46711571644SToomas Soome						4 value_buffer strget
46811571644SToomas Soome						strcat	( addr len )
46911571644SToomas Soome						s" :" strcat
47011571644SToomas Soome					then
47111571644SToomas Soome				then
47211571644SToomas Soome
473199767f8SToomas Soome				52 i +			\ ascii 4 + i
474199767f8SToomas Soome				s" bootenv_root[4]" 13 +c! setenv
47511571644SToomas Soome				device free-memory 0 to device
476199767f8SToomas Soome				free_buffers
477568506e1SToomas Soome				-1
478568506e1SToomas Soome			+loop
479199767f8SToomas Soome
480199767f8SToomas Soome			5 count do		\ unset unused entries
481199767f8SToomas Soome				52 i +			\ ascii 4 + i
482199767f8SToomas Soome				dup s" bootenvmenu_caption[4]" 20 +c! unsetenv
483199767f8SToomas Soome				dup s" bootenvansi_caption[4]" 20 +c! unsetenv
484199767f8SToomas Soome				dup s" bootenvmenu_command[4]" 20 +c! unsetenv
485199767f8SToomas Soome				s" bootenv_root[4]" 13 +c! unsetenv
486199767f8SToomas Soome			loop
487199767f8SToomas Soome
488199767f8SToomas Soome			1 to end_of_file?		\ we are done
489199767f8SToomas Soome		then
490199767f8SToomas Soome	repeat
491199767f8SToomas Soome	fd @ fclose
492199767f8SToomas Soome	line_buffer strfree
493199767f8SToomas Soome	read_buffer strfree
494199767f8SToomas Soome;
495