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 int luaopen_freebsd_kenv(lua_State *L);
18
19 static int
lua_kenv_get(lua_State * L)20 lua_kenv_get(lua_State *L)
21 {
22 const char *env;
23 int ret, n;
24 char value[1024];
25
26 n = lua_gettop(L);
27 if (n == 0) {
28 char *buf, *bp, *cp;
29 int size;
30
31 size = kenv(KENV_DUMP, NULL, NULL, 0);
32 if (size < 0) {
33 lua_pushnil(L);
34 lua_pushstring(L, strerror(errno));
35 lua_pushinteger(L, errno);
36 return (3);
37 }
38 size += 1;
39 buf = malloc(size);
40 if (buf == NULL) {
41 lua_pushnil(L);
42 lua_pushstring(L, strerror(errno));
43 lua_pushinteger(L, errno);
44 return (3);
45 }
46 if (kenv(KENV_DUMP, NULL, buf, size) < 0) {
47 free(buf);
48 lua_pushnil(L);
49 lua_pushstring(L, strerror(errno));
50 lua_pushinteger(L, errno);
51 return (3);
52 }
53
54 lua_newtable(L);
55 for (bp = buf; *bp != '\0'; bp += strlen(bp) + 1) {
56 cp = strchr(bp, '=');
57 if (cp == NULL)
58 continue;
59 *cp++ = '\0';
60 lua_pushstring(L, cp);
61 lua_setfield(L, -2, bp);
62 bp = cp;
63 }
64 free(buf);
65 return (1);
66 }
67 env = luaL_checkstring(L, 1);
68 ret = kenv(KENV_GET, env, value, sizeof(value));
69 if (ret == -1) {
70 if (errno == ENOENT) {
71 lua_pushnil(L);
72 return (1);
73 }
74 lua_pushnil(L);
75 lua_pushstring(L, strerror(errno));
76 lua_pushinteger(L, errno);
77 return (3);
78 }
79 lua_pushstring(L, value);
80 return (1);
81 }
82
83 #define REG_SIMPLE(n) { #n, lua_kenv_ ## n }
84 static const struct luaL_Reg freebsd_kenv[] = {
85 REG_SIMPLE(get),
86 { NULL, NULL },
87 };
88 #undef REG_SIMPLE
89
90 int
luaopen_freebsd_kenv(lua_State * L)91 luaopen_freebsd_kenv(lua_State *L)
92 {
93 luaL_newlib(L, freebsd_kenv);
94
95 return (1);
96 }
97