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