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