xref: /freebsd/libexec/flua/libfreebsd/kenv/kenv.c (revision 696922fbfa3e1c400701a3a39dcadf7dee12b06c)
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