From c69a31795b0ec00525d37ef0f0a9828a56ecf991 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 24 Nov 2022 09:16:05 +0100 Subject: flua: add a chown(2) binding The main difference with the chown in luaposix, is that it checks and reports if a user or a group do exist when a string is passed as arguments Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D37479 (cherry picked from commit a1ab15abe2e2a1ed92cbad056df71afff7e8794e) --- libexec/flua/modules/lposix.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/libexec/flua/modules/lposix.c b/libexec/flua/modules/lposix.c index adf3a7bb9a1f..88687be2788c 100644 --- a/libexec/flua/modules/lposix.c +++ b/libexec/flua/modules/lposix.c @@ -30,6 +30,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include @@ -63,6 +65,62 @@ lua_chmod(lua_State *L) return 1; } +static int +lua_chown(lua_State *L) +{ + int n; + const char *path; + uid_t owner = (uid_t) -1; + gid_t group = (gid_t) -1; + + n = lua_gettop(L); + luaL_argcheck(L, n > 1, n, + "chown takes at least two arguments"); + path = luaL_checkstring(L, 1); + if (lua_isinteger(L, 2)) + owner = (uid_t) lua_tointeger(L, 2); + else if (lua_isstring(L, 2)) { + struct passwd *p = getpwnam(lua_tostring(L, 2)); + if (p != NULL) + owner = p->pw_uid; + else + return (luaL_argerror(L, 2, + lua_pushfstring(L, "unknown user %s", + lua_tostring(L, 2)))); + } else if (!lua_isnoneornil(L, 2)) { + const char *type = luaL_typename(L, 2); + return (luaL_argerror(L, 2, + lua_pushfstring(L, "integer or string expected, got %s", + type))); + } + + if (lua_isinteger(L, 3)) + group = (gid_t) lua_tointeger(L, 3); + else if (lua_isstring(L, 3)) { + struct group *g = getgrnam(lua_tostring(L, 3)); + if (g != NULL) + group = g->gr_gid; + else + return (luaL_argerror(L, 3, + lua_pushfstring(L, "unknown user %s", + lua_tostring(L, 3)))); + } else if (!lua_isnoneornil(L, 3)) { + const char *type = luaL_typename(L, 3); + return (luaL_argerror(L, 3, + lua_pushfstring(L, "integer or string expected, got %s", + type))); + } + + if (chown(path, owner, group) == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + lua_pushinteger(L, 0); + return (1); +} + static int lua_getpid(lua_State *L) { @@ -82,6 +140,7 @@ static const struct luaL_Reg sys_statlib[] = { static const struct luaL_Reg unistdlib[] = { REG_SIMPLE(getpid), + REG_SIMPLE(chown), { NULL, NULL }, }; #undef REG_SIMPLE -- cgit v1.2.3