1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024, Baptiste Daroussin <bapt@FreeBSD.org> 5 */ 6 7 #include <errno.h> 8 #include <kenv.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include <lua.h> 14 #include <lualib.h> 15 #include <lauxlib.h> 16 17 #include "bootstrap.h" 18 19 int luaopen_freebsd_kenv(lua_State *L); 20 21 static int 22 lua_kenv_get(lua_State *L) 23 { 24 const char *env; 25 int ret, n; 26 char value[1024]; 27 28 n = lua_gettop(L); 29 if (n == 0) { 30 char *buf, *bp, *cp; 31 int size; 32 33 size = kenv(KENV_DUMP, NULL, NULL, 0); 34 if (size < 0) { 35 lua_pushnil(L); 36 lua_pushstring(L, strerror(errno)); 37 lua_pushinteger(L, errno); 38 return (3); 39 } 40 size += 1; 41 buf = malloc(size); 42 if (buf == NULL) { 43 lua_pushnil(L); 44 lua_pushstring(L, strerror(errno)); 45 lua_pushinteger(L, errno); 46 return (3); 47 } 48 if (kenv(KENV_DUMP, NULL, buf, size) < 0) { 49 free(buf); 50 lua_pushnil(L); 51 lua_pushstring(L, strerror(errno)); 52 lua_pushinteger(L, errno); 53 return (3); 54 } 55 56 lua_newtable(L); 57 for (bp = buf; *bp != '\0'; bp += strlen(bp) + 1) { 58 cp = strchr(bp, '='); 59 if (cp == NULL) 60 continue; 61 *cp++ = '\0'; 62 lua_pushstring(L, cp); 63 lua_setfield(L, -2, bp); 64 bp = cp; 65 } 66 free(buf); 67 return (1); 68 } 69 env = luaL_checkstring(L, 1); 70 ret = kenv(KENV_GET, env, value, sizeof(value)); 71 if (ret == -1) { 72 if (errno == ENOENT) { 73 lua_pushnil(L); 74 return (1); 75 } 76 lua_pushnil(L); 77 lua_pushstring(L, strerror(errno)); 78 lua_pushinteger(L, errno); 79 return (3); 80 } 81 lua_pushstring(L, value); 82 return (1); 83 } 84 85 #define REG_SIMPLE(n) { #n, lua_kenv_ ## n } 86 static const struct luaL_Reg freebsd_kenv[] = { 87 REG_SIMPLE(get), 88 { NULL, NULL }, 89 }; 90 #undef REG_SIMPLE 91 92 int 93 luaopen_freebsd_kenv(lua_State *L) 94 { 95 luaL_newlib(L, freebsd_kenv); 96 97 return (1); 98 } 99 100 FLUA_MODULE_NAMED(freebsd_kenv, "freebsd.kenv"); 101