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