env.c revision 329099
1139749Simp/* 276479Swpaul * Copyright (c) 2015 Netflix, Inc. All Rights Reserved. 376479Swpaul * 476479Swpaul * Redistribution and use in source and binary forms, with or without 576479Swpaul * modification, are permitted provided that the following conditions 676479Swpaul * are met: 776479Swpaul * 1. Redistributions of source code must retain the above copyright 876479Swpaul * notice, this list of conditions and the following disclaimer. 976479Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1076479Swpaul * notice, this list of conditions and the following disclaimer in the 1176479Swpaul * documentation and/or other materials provided with the distribution. 1276479Swpaul * 1376479Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1476479Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1576479Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1676479Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1776479Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1876479Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1976479Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2076479Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2176479Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2276479Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2376479Swpaul * SUCH DAMAGE. 2476479Swpaul */ 2576479Swpaul 2676479Swpaul#include <sys/cdefs.h> 2776479Swpaul__FBSDID("$FreeBSD: stable/11/sys/boot/efi/libefi/env.c 329099 2018-02-10 04:37:44Z kevans $"); 2876479Swpaul 2976479Swpaul#include <sys/param.h> 3076479Swpaul#include <stand.h> 3176479Swpaul#include <string.h> 3276479Swpaul#include <efi.h> 3376479Swpaul#include <efilib.h> 34119418Sobrien#include <uuid.h> 35119418Sobrien#include <stdbool.h> 36119418Sobrien#include "bootstrap.h" 3776479Swpaul#ifdef BOOT_FORTH 3876479Swpaul#include "ficl.h" 3976479Swpaul#endif 4076479Swpaul 4176479Swpaul/* 4276479Swpaul * Simple wrappers to the underlying UEFI functions. 4376479Swpaul * See http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES 4476479Swpaul * for details. 4576479Swpaul */ 4676479SwpaulEFI_STATUS 4776479Swpaulefi_get_next_variable_name(UINTN *variable_name_size, CHAR16 *variable_name, 4876479Swpaul EFI_GUID *vendor_guid) 4976479Swpaul{ 5076479Swpaul return (RS->GetNextVariableName(variable_name_size, variable_name, 5176479Swpaul vendor_guid)); 5276479Swpaul} 5376479Swpaul 5476479SwpaulEFI_STATUS 5576479Swpaulefi_get_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, 5676479Swpaul UINT32 *attributes, UINTN *data_size, void *data) 5776479Swpaul{ 5876479Swpaul return (RS->GetVariable(variable_name, vendor_guid, attributes, 5976479Swpaul data_size, data)); 6076479Swpaul} 6176479Swpaul 6276479SwpaulEFI_STATUS 6376479Swpaulefi_set_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, 6476479Swpaul UINT32 attributes, UINTN data_size, void *data) 6576479Swpaul{ 6676479Swpaul return (RS->SetVariable(variable_name, vendor_guid, attributes, 6776479Swpaul data_size, data)); 6876479Swpaul} 6976479Swpaul 7076479Swpaulvoid 7176479Swpaulefi_init_environment(void) 7276479Swpaul{ 7378323Swpaul char var[128]; 7478323Swpaul 7578323Swpaul snprintf(var, sizeof(var), "%d.%02d", ST->Hdr.Revision >> 16, 7678323Swpaul ST->Hdr.Revision & 0xffff); 7778323Swpaul env_setenv("efi-version", EV_VOLATILE, var, env_noset, env_nounset); 7878323Swpaul} 7978323Swpaul 8078323SwpaulCOMMAND_SET(efishow, "efi-show", "print some or all EFI variables", command_efi_show); 8178323Swpaul 8278323Swpaulstatic int 8378323Swpaulefi_print_var(CHAR16 *varnamearg, EFI_GUID *matchguid, int lflag) 8478323Swpaul{ 8578323Swpaul UINTN datasz, i; 8678323Swpaul EFI_STATUS status; 8778323Swpaul UINT32 attr; 8878323Swpaul CHAR16 *data; 8976479Swpaul char *str; 9076479Swpaul uint32_t uuid_status; 91150968Sglebius int is_ascii; 92150968Sglebius 93150968Sglebius datasz = 0; 94150968Sglebius status = RS->GetVariable(varnamearg, matchguid, &attr, 9576479Swpaul &datasz, NULL); 9676479Swpaul if (status != EFI_BUFFER_TOO_SMALL) { 9776479Swpaul printf("Can't get the variable: error %#lx\n", 9876479Swpaul EFI_ERROR_CODE(status)); 9976479Swpaul return (CMD_ERROR); 100129879Sphk } 10176479Swpaul data = malloc(datasz); 10276479Swpaul status = RS->GetVariable(varnamearg, matchguid, &attr, 10376479Swpaul &datasz, data); 10476479Swpaul if (status != EFI_SUCCESS) { 10576479Swpaul printf("Can't get the variable: error %#lx\n", 10676479Swpaul EFI_ERROR_CODE(status)); 10776479Swpaul return (CMD_ERROR); 10876479Swpaul } 10976479Swpaul uuid_to_string((uuid_t *)matchguid, &str, &uuid_status); 11076479Swpaul if (lflag) { 11176479Swpaul printf("%s 0x%x %S", str, attr, varnamearg); 11276479Swpaul } else { 11376479Swpaul printf("%s 0x%x %S=", str, attr, varnamearg); 11476479Swpaul is_ascii = 1; 11576479Swpaul free(str); 11676479Swpaul str = (char *)data; 11776479Swpaul for (i = 0; i < datasz - 1; i++) { 11876479Swpaul /* Quick hack to see if this ascii-ish string printable range plus tab, cr and lf */ 11976479Swpaul if ((str[i] < 32 || str[i] > 126) && str[i] != 9 && str[i] != 10 && str[i] != 13) { 12076479Swpaul is_ascii = 0; 12176479Swpaul break; 12276479Swpaul } 12376479Swpaul } 124119285Simp if (str[datasz - 1] != '\0') 125119285Simp is_ascii = 0; 12676479Swpaul if (is_ascii) 12776479Swpaul printf("%s", str); 12876479Swpaul else { 12976522Swpaul for (i = 0; i < datasz / 2; i++) { 13076479Swpaul if (isalnum(data[i]) || isspace(data[i])) 131113506Smdodd printf("%c", data[i]); 132113506Smdodd else 13376479Swpaul printf("\\x%02x", data[i]); 13476479Swpaul } 135151545Simp } 13676479Swpaul } 13776479Swpaul free(data); 13876479Swpaul if (pager_output("\n")) 13976479Swpaul return (CMD_WARN); 14076479Swpaul return (CMD_OK); 14176479Swpaul} 14276479Swpaul 14376479Swpaulstatic int 14476479Swpaulcommand_efi_show(int argc, char *argv[]) 14576479Swpaul{ 14676479Swpaul /* 14776479Swpaul * efi-show [-a] 14876479Swpaul * print all the env 14999497Salfred * efi-show -u UUID 15099497Salfred * print all the env vars tagged with UUID 15199497Salfred * efi-show -v var 15276479Swpaul * search all the env vars and print the ones matching var 15399497Salfred * eif-show -u UUID -v var 15499497Salfred * eif-show UUID var 155135254Salc * print all the env vars that match UUID and var 156135250Swpaul */ 157135250Swpaul /* NB: We assume EFI_GUID is the same as uuid_t */ 15899497Salfred int aflag = 0, gflag = 0, lflag = 0, vflag = 0; 15999497Salfred int ch, rv; 16099497Salfred unsigned i; 16199497Salfred EFI_STATUS status; 16299497Salfred EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} }; 163135250Swpaul EFI_GUID matchguid = { 0,0,0,{0,0,0,0,0,0,0,0} }; 16499497Salfred uint32_t uuid_status; 16599497Salfred CHAR16 *varname; 166135250Swpaul CHAR16 *newnm; 16799497Salfred CHAR16 varnamearg[128]; 16899497Salfred UINTN varalloc; 169173839Syongari UINTN varsz; 17099497Salfred 171151296Sjhb while ((ch = getopt(argc, argv, "ag:lv:")) != -1) { 17299497Salfred switch (ch) { 17376479Swpaul case 'a': 17499497Salfred aflag = 1; 17599497Salfred break; 17699497Salfred case 'g': 17799497Salfred gflag = 1; 17899497Salfred uuid_from_string(optarg, (uuid_t *)&matchguid, 17976479Swpaul &uuid_status); 18099497Salfred if (uuid_status != uuid_s_ok) { 18199497Salfred printf("uid %s could not be parsed\n", optarg); 18299497Salfred return (CMD_ERROR); 18399497Salfred } 18476479Swpaul break; 18599497Salfred case 'l': 18699497Salfred lflag = 1; 18799497Salfred break; 18876479Swpaul case 'v': 18999497Salfred vflag = 1; 19099497Salfred if (strlen(optarg) >= nitems(varnamearg)) { 19199497Salfred printf("Variable %s is longer than %zd characters\n", 19299497Salfred optarg, nitems(varnamearg)); 19376479Swpaul return (CMD_ERROR); 19476479Swpaul } 19576479Swpaul for (i = 0; i < strlen(optarg); i++) 19676479Swpaul varnamearg[i] = optarg[i]; 19776479Swpaul varnamearg[i] = 0; 19876479Swpaul break; 19976479Swpaul default: 20076479Swpaul printf("Invalid argument %c\n", ch); 20176479Swpaul return (CMD_ERROR); 20276479Swpaul } 20376479Swpaul } 20476479Swpaul 20576479Swpaul if (aflag && (gflag || vflag)) { 20676479Swpaul printf("-a isn't compatible with -v or -u\n"); 20776479Swpaul return (CMD_ERROR); 20876479Swpaul } 20976479Swpaul 21076479Swpaul if (aflag && optind < argc) { 21176479Swpaul printf("-a doesn't take any args\n"); 21276479Swpaul return (CMD_ERROR); 21376479Swpaul } 21476479Swpaul 21576479Swpaul if (optind == argc) 21676479Swpaul aflag = 1; 21776479Swpaul 21876479Swpaul argc -= optind; 21976479Swpaul argv += optind; 22076479Swpaul 22176479Swpaul pager_open(); 22276479Swpaul if (vflag && gflag) { 22376479Swpaul rv = efi_print_var(varnamearg, &matchguid, lflag); 22476479Swpaul pager_close(); 22576479Swpaul return (rv); 22676479Swpaul } 22776479Swpaul 22876479Swpaul if (argc == 2) { 229113506Smdodd optarg = argv[0]; 23076479Swpaul if (strlen(optarg) >= nitems(varnamearg)) { 23176479Swpaul printf("Variable %s is longer than %zd characters\n", 23276479Swpaul optarg, nitems(varnamearg)); 23376479Swpaul pager_close(); 23476479Swpaul return (CMD_ERROR); 23576479Swpaul } 23676479Swpaul for (i = 0; i < strlen(optarg); i++) 23776479Swpaul varnamearg[i] = optarg[i]; 23876479Swpaul varnamearg[i] = 0; 23976479Swpaul optarg = argv[1]; 24076479Swpaul uuid_from_string(optarg, (uuid_t *)&matchguid, 241106696Salfred &uuid_status); 24276479Swpaul if (uuid_status != uuid_s_ok) { 24376479Swpaul printf("uid %s could not be parsed\n", optarg); 244106696Salfred pager_close(); 24576479Swpaul return (CMD_ERROR); 24699497Salfred } 247192288Syongari rv = efi_print_var(varnamearg, &matchguid, lflag); 24876479Swpaul pager_close(); 24976479Swpaul return (rv); 25076479Swpaul } 25176479Swpaul 25276479Swpaul if (argc > 0) { 25376479Swpaul printf("Too many args %d\n", argc); 25476479Swpaul pager_close(); 25576479Swpaul return (CMD_ERROR); 25676479Swpaul } 25799497Salfred 258192288Syongari /* 25976479Swpaul * Initiate the search -- note the standard takes pain 260192289Syongari * to specify the initial call must be a poiner to a NULL 26176479Swpaul * character. 26276479Swpaul */ 26376479Swpaul varalloc = 1024; 26476479Swpaul varname = malloc(varalloc); 26576479Swpaul if (varname == NULL) { 26676479Swpaul printf("Can't allocate memory to get variables\n"); 26776479Swpaul pager_close(); 26876479Swpaul return (CMD_ERROR); 26976479Swpaul } 27076479Swpaul varname[0] = 0; 27176479Swpaul while (1) { 27276479Swpaul varsz = varalloc; 27376479Swpaul status = RS->GetNextVariableName(&varsz, varname, &varguid); 27476479Swpaul if (status == EFI_BUFFER_TOO_SMALL) { 27576479Swpaul varalloc = varsz; 27676479Swpaul newnm = realloc(varname, varalloc); 27776479Swpaul if (newnm == NULL) { 27876479Swpaul printf("Can't allocate memory to get variables\n"); 27976479Swpaul free(varname); 28076479Swpaul pager_close(); 28176479Swpaul return (CMD_ERROR); 28276479Swpaul } 28376479Swpaul varname = newnm; 28476479Swpaul continue; /* Try again with bigger buffer */ 28576479Swpaul } 28699497Salfred if (status != EFI_SUCCESS) 287192288Syongari break; 28876479Swpaul if (aflag) { 289192289Syongari if (efi_print_var(varname, &varguid, lflag) != CMD_OK) 29076479Swpaul break; 29176479Swpaul continue; 29276479Swpaul } 29376479Swpaul if (vflag) { 29476479Swpaul if (wcscmp(varnamearg, varname) == 0) { 29576479Swpaul if (efi_print_var(varname, &varguid, lflag) != CMD_OK) 29676479Swpaul break; 29776479Swpaul continue; 29876479Swpaul } 29976479Swpaul } 30076479Swpaul if (gflag) { 30176479Swpaul if (memcmp(&varguid, &matchguid, sizeof(varguid)) == 0) { 30276479Swpaul if (efi_print_var(varname, &varguid, lflag) != CMD_OK) 30376479Swpaul break; 30476479Swpaul continue; 30576479Swpaul } 30676479Swpaul } 30776479Swpaul } 30876479Swpaul free(varname); 30976479Swpaul pager_close(); 31076479Swpaul 31176479Swpaul return (CMD_OK); 31276479Swpaul} 31376479Swpaul 31476479SwpaulCOMMAND_SET(efiset, "efi-set", "set EFI variables", command_efi_set); 31599497Salfred 316192288Syongaristatic int 31776479Swpaulcommand_efi_set(int argc, char *argv[]) 318192289Syongari{ 31976479Swpaul char *uuid, *var, *val; 32076479Swpaul CHAR16 wvar[128]; 32176479Swpaul EFI_GUID guid; 32276479Swpaul uint32_t status; 32376479Swpaul EFI_STATUS err; 32476479Swpaul 32576479Swpaul if (argc != 4) { 32676479Swpaul printf("efi-set uuid var new-value\n"); 32776479Swpaul return (CMD_ERROR); 32876479Swpaul } 32976479Swpaul uuid = argv[1]; 33076479Swpaul var = argv[2]; 33176479Swpaul val = argv[3]; 33276479Swpaul uuid_from_string(uuid, (uuid_t *)&guid, &status); 33376479Swpaul if (status != uuid_s_ok) { 33476479Swpaul printf("Invalid uuid %s %d\n", uuid, status); 33576479Swpaul return (CMD_ERROR); 33676479Swpaul } 33776479Swpaul cpy8to16(var, wvar, sizeof(wvar)); 33876479Swpaul err = RS->SetVariable(wvar, &guid, 33976479Swpaul EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 34076479Swpaul strlen(val) + 1, val); 34176479Swpaul if (EFI_ERROR(err)) { 34276479Swpaul printf("Failed to set variable: error %lu\n", EFI_ERROR_CODE(err)); 34376479Swpaul return (CMD_ERROR); 34476479Swpaul } 34576479Swpaul return (CMD_OK); 34676479Swpaul} 34776479Swpaul 34876479SwpaulCOMMAND_SET(efiunset, "efi-unset", "delete / unset EFI variables", command_efi_unset); 34976479Swpaul 35076479Swpaulstatic int 35176479Swpaulcommand_efi_unset(int argc, char *argv[]) 35276479Swpaul{ 35376479Swpaul char *uuid, *var; 35476479Swpaul CHAR16 wvar[128]; 35576479Swpaul EFI_GUID guid; 35676479Swpaul uint32_t status; 35776479Swpaul EFI_STATUS err; 35876479Swpaul 35976479Swpaul if (argc != 3) { 36099497Salfred printf("efi-unset uuid var\n"); 361192288Syongari return (CMD_ERROR); 36276479Swpaul } 36376479Swpaul uuid = argv[1]; 36476479Swpaul var = argv[2]; 36576479Swpaul uuid_from_string(uuid, (uuid_t *)&guid, &status); 36676479Swpaul if (status != uuid_s_ok) { 36776479Swpaul printf("Invalid uuid %s\n", uuid); 36876479Swpaul return (CMD_ERROR); 36976479Swpaul } 37076479Swpaul cpy8to16(var, wvar, sizeof(wvar)); 37176479Swpaul err = RS->SetVariable(wvar, &guid, 0, 0, NULL); 37276479Swpaul if (EFI_ERROR(err)) { 37376479Swpaul printf("Failed to unset variable: error %lu\n", EFI_ERROR_CODE(err)); 37476479Swpaul return (CMD_ERROR); 37576479Swpaul } 37676479Swpaul return (CMD_OK); 37776479Swpaul} 37876479Swpaul 37976479Swpaul#ifdef BOOT_FORTH 38076479Swpaul/* 38199497Salfred * FreeBSD's loader interaction words and extras 382192288Syongari * 38376479Swpaul * efi-setenv ( value n name n guid n attr -- 0 | -1) 384192289Syongari * efi-getenv ( guid n addr n -- addr' n' | -1 ) 38576479Swpaul * efi-unsetenv ( name n guid n'' -- ) 38676479Swpaul */ 38776479Swpaul 38876479Swpaul/* 38976479Swpaul * efi-setenv 39076479Swpaul * efi-setenv ( value n name n guid n attr -- 0 | -1) 39176479Swpaul * 39276479Swpaul * Set environment variables using the SetVariable EFI runtime service. 39376479Swpaul * 39476479Swpaul * Value and guid are passed through in binary form (so guid needs to be 39576479Swpaul * converted to binary form from its string form). Name is converted from 39676479Swpaul * ASCII to CHAR16. Since ficl doesn't have support for internationalization, 39776479Swpaul * there's no native CHAR16 interface provided. 39876479Swpaul * 39976479Swpaul * attr is an int in the bitmask of the following attributes for this variable. 40076479Swpaul * 40199497Salfred * 1 Non volatile 402192288Syongari * 2 Boot service access 40376479Swpaul * 4 Run time access 40476479Swpaul * (corresponding to the same bits in the UEFI spec). 40576479Swpaul */ 40676479Swpaulstatic void 40776479SwpaulficlEfiSetenv(FICL_VM *pVM) 40876479Swpaul{ 40976479Swpaul char *value = NULL, *guid = NULL; 41076479Swpaul CHAR16 *name = NULL; 41176479Swpaul int i; 41276479Swpaul char *namep, *valuep, *guidp; 41376479Swpaul int names, values, guids, attr; 41476479Swpaul EFI_STATUS status; 41576479Swpaul uuid_t u; 41676479Swpaul uint32_t ustatus; 41776479Swpaul bool error = true; 41876479Swpaul 41976479Swpaul#if FICL_ROBUST > 1 42076479Swpaul vmCheckStack(pVM, 6, 0); 42176479Swpaul#endif 42276479Swpaul attr = stackPopINT(pVM->pStack); 42376479Swpaul guids = stackPopINT(pVM->pStack); 42499497Salfred guidp = (char*)stackPopPtr(pVM->pStack); 425192288Syongari names = stackPopINT(pVM->pStack); 42676479Swpaul namep = (char*)stackPopPtr(pVM->pStack); 427135250Swpaul values = stackPopINT(pVM->pStack); 42876479Swpaul valuep = (char*)stackPopPtr(pVM->pStack); 42976479Swpaul 43076479Swpaul guid = (char*)ficlMalloc(guids); 43176479Swpaul if (guid == NULL) 43276479Swpaul goto out; 43376479Swpaul memcpy(guid, guidp, guids); 43476479Swpaul uuid_from_string(guid, &u, &ustatus); 43576479Swpaul if (ustatus != uuid_s_ok) { 43676479Swpaul stackPushINT(pVM->pStack, -1); 43776479Swpaul goto out; 43876479Swpaul } 43976479Swpaul 44076479Swpaul name = ficlMalloc((names + 1) * sizeof(CHAR16)); 44176479Swpaul if (name == NULL) 44276479Swpaul goto out; 44376479Swpaul for (i = 0; i < names; i++) 44476479Swpaul name[i] = namep[i]; 44576479Swpaul name[names] = 0; 44676479Swpaul 44776479Swpaul value = ficlMalloc(values + 1); 44876479Swpaul if (value == NULL) 44976479Swpaul goto out; 45076479Swpaul memcpy(value, valuep, values); 45176479Swpaul 45276479Swpaul status = efi_set_variable(name, (EFI_GUID *)&u, attr, values, value); 45376479Swpaul if (status == EFI_SUCCESS) 45476479Swpaul stackPushINT(pVM->pStack, 0); 45576479Swpaul else 45676479Swpaul stackPushINT(pVM->pStack, -1); 45776479Swpaul error = false; 45876479Swpaulout: 45976479Swpaul ficlFree(name); 46076479Swpaul ficlFree(value); 46176479Swpaul ficlFree(guid); 46276479Swpaul 46376479Swpaul if (error == true) 46476479Swpaul vmThrowErr(pVM, "Error: out of memory"); 465109058Smbr} 46676479Swpaul 46776479Swpaulstatic void 46876479SwpaulficlEfiGetenv(FICL_VM *pVM) 46976479Swpaul{ 47076479Swpaul char *name, *value; 47176479Swpaul char *namep; 47276479Swpaul int names; 47376479Swpaul 47476479Swpaul#if FICL_ROBUST > 1 47576479Swpaul vmCheckStack(pVM, 2, 2); 47676479Swpaul#endif 47776479Swpaul names = stackPopINT(pVM->pStack); 47876479Swpaul namep = (char*) stackPopPtr(pVM->pStack); 47976479Swpaul 48076479Swpaul name = (char*) ficlMalloc(names+1); 48176479Swpaul if (name == NULL) 48276479Swpaul vmThrowErr(pVM, "Error: out of memory"); 48376479Swpaul strncpy(name, namep, names); 48476479Swpaul name[names] = '\0'; 48576479Swpaul 48676479Swpaul value = getenv(name); 48776479Swpaul ficlFree(name); 48876479Swpaul 48976479Swpaul if(value != NULL) { 49076479Swpaul stackPushPtr(pVM->pStack, value); 49176479Swpaul stackPushINT(pVM->pStack, strlen(value)); 49276479Swpaul } else 49376479Swpaul stackPushINT(pVM->pStack, -1); 49476479Swpaul} 49576479Swpaul 49676479Swpaulstatic void 49776479SwpaulficlEfiUnsetenv(FICL_VM *pVM) 49876479Swpaul{ 49976479Swpaul char *name; 50076479Swpaul char *namep; 50176479Swpaul int names; 50276479Swpaul 50376479Swpaul#if FICL_ROBUST > 1 50476479Swpaul vmCheckStack(pVM, 2, 0); 50576479Swpaul#endif 50676479Swpaul names = stackPopINT(pVM->pStack); 50776479Swpaul namep = (char*) stackPopPtr(pVM->pStack); 50876479Swpaul 50976479Swpaul name = (char*) ficlMalloc(names+1); 51099497Salfred if (name == NULL) 511192288Syongari vmThrowErr(pVM, "Error: out of memory"); 51276479Swpaul strncpy(name, namep, names); 51376479Swpaul name[names] = '\0'; 51476479Swpaul 51576479Swpaul unsetenv(name); 51676479Swpaul ficlFree(name); 51776479Swpaul} 51876479Swpaul 51976479Swpaul/************************************************************************** 52076479Swpaul** Add FreeBSD UEFI platform extensions into the system dictionary 52176479Swpaul**************************************************************************/ 52276479Swpaulvoid ficlEfiCompilePlatform(FICL_SYSTEM *pSys) 52376479Swpaul{ 52476479Swpaul FICL_DICT *dp = pSys->dp; 52576479Swpaul assert (dp); 52676479Swpaul 52776479Swpaul dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT); 52876479Swpaul dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT); 52976479Swpaul dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT); 53076479Swpaul} 53176479Swpaul 53276479SwpaulFICL_COMPILE_SET(ficlEfiCompilePlatform); 53376479Swpaul 53476479Swpaul#endif /* BOOT_FORTH */ 53576479Swpaul