1506f3640SKyle Evans /*- 2506f3640SKyle Evans * Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 3506f3640SKyle Evans * 4506f3640SKyle Evans * Redistribution and use in source and binary forms, with or without 5506f3640SKyle Evans * modification, are permitted provided that the following conditions 6506f3640SKyle Evans * are met: 7506f3640SKyle Evans * 1. Redistributions of source code must retain the above copyright 8506f3640SKyle Evans * notice, this list of conditions and the following disclaimer. 9506f3640SKyle Evans * 2. Redistributions in binary form must reproduce the above copyright 10506f3640SKyle Evans * notice, this list of conditions and the following disclaimer in the 11506f3640SKyle Evans * documentation and/or other materials provided with the distribution. 12506f3640SKyle Evans * 13506f3640SKyle Evans * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14506f3640SKyle Evans * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15506f3640SKyle Evans * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16506f3640SKyle Evans * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17506f3640SKyle Evans * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18506f3640SKyle Evans * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19506f3640SKyle Evans * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20506f3640SKyle Evans * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21506f3640SKyle Evans * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22506f3640SKyle Evans * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23506f3640SKyle Evans * SUCH DAMAGE. 24506f3640SKyle Evans * 25506f3640SKyle Evans */ 26506f3640SKyle Evans 27506f3640SKyle Evans #include <sys/cdefs.h> 28506f3640SKyle Evans __FBSDID("$FreeBSD$"); 29506f3640SKyle Evans 30405e3338SEd Maste #include <sys/stat.h> 31405e3338SEd Maste 32405e3338SEd Maste #include <errno.h> 33a1ab15abSBaptiste Daroussin #include <grp.h> 34a1ab15abSBaptiste Daroussin #include <pwd.h> 35405e3338SEd Maste #include <string.h> 36506f3640SKyle Evans #include <unistd.h> 37506f3640SKyle Evans 38506f3640SKyle Evans #include <lua.h> 39506f3640SKyle Evans #include "lauxlib.h" 40506f3640SKyle Evans #include "lposix.h" 41506f3640SKyle Evans 42506f3640SKyle Evans /* 43506f3640SKyle Evans * Minimal implementation of luaposix needed for internal FreeBSD bits. 44506f3640SKyle Evans */ 45506f3640SKyle Evans 46506f3640SKyle Evans static int 47405e3338SEd Maste lua_chmod(lua_State *L) 48405e3338SEd Maste { 49405e3338SEd Maste int n; 50405e3338SEd Maste const char *path; 51405e3338SEd Maste mode_t mode; 52405e3338SEd Maste 53405e3338SEd Maste n = lua_gettop(L); 54405e3338SEd Maste luaL_argcheck(L, n == 2, n > 2 ? 3 : n, 55405e3338SEd Maste "chmod takes exactly two arguments"); 56405e3338SEd Maste path = luaL_checkstring(L, 1); 57405e3338SEd Maste mode = (mode_t)luaL_checkinteger(L, 2); 58405e3338SEd Maste if (chmod(path, mode) == -1) { 59405e3338SEd Maste lua_pushnil(L); 60405e3338SEd Maste lua_pushstring(L, strerror(errno)); 61405e3338SEd Maste lua_pushinteger(L, errno); 62405e3338SEd Maste return 3; 63405e3338SEd Maste } 64405e3338SEd Maste lua_pushinteger(L, 0); 65405e3338SEd Maste return 1; 66405e3338SEd Maste } 67405e3338SEd Maste 68405e3338SEd Maste static int 69a1ab15abSBaptiste Daroussin lua_chown(lua_State *L) 70a1ab15abSBaptiste Daroussin { 71a1ab15abSBaptiste Daroussin int n; 72a1ab15abSBaptiste Daroussin const char *path; 73a1ab15abSBaptiste Daroussin uid_t owner = (uid_t) -1; 74a1ab15abSBaptiste Daroussin gid_t group = (gid_t) -1; 75a1ab15abSBaptiste Daroussin 76a1ab15abSBaptiste Daroussin n = lua_gettop(L); 77a1ab15abSBaptiste Daroussin luaL_argcheck(L, n > 1, n, 78a1ab15abSBaptiste Daroussin "chown takes at least two arguments"); 79a1ab15abSBaptiste Daroussin path = luaL_checkstring(L, 1); 80a1ab15abSBaptiste Daroussin if (lua_isinteger(L, 2)) 81a1ab15abSBaptiste Daroussin owner = (uid_t) lua_tointeger(L, 2); 82a1ab15abSBaptiste Daroussin else if (lua_isstring(L, 2)) { 83a1ab15abSBaptiste Daroussin struct passwd *p = getpwnam(lua_tostring(L, 2)); 84a1ab15abSBaptiste Daroussin if (p != NULL) 85a1ab15abSBaptiste Daroussin owner = p->pw_uid; 86a1ab15abSBaptiste Daroussin else 87a1ab15abSBaptiste Daroussin return (luaL_argerror(L, 2, 88a1ab15abSBaptiste Daroussin lua_pushfstring(L, "unknown user %s", 89a1ab15abSBaptiste Daroussin lua_tostring(L, 2)))); 90a1ab15abSBaptiste Daroussin } else if (!lua_isnoneornil(L, 2)) { 91a1ab15abSBaptiste Daroussin const char *type = luaL_typename(L, 2); 92a1ab15abSBaptiste Daroussin return (luaL_argerror(L, 2, 93a1ab15abSBaptiste Daroussin lua_pushfstring(L, "integer or string expected, got %s", 94a1ab15abSBaptiste Daroussin type))); 95a1ab15abSBaptiste Daroussin } 96a1ab15abSBaptiste Daroussin 97a1ab15abSBaptiste Daroussin if (lua_isinteger(L, 3)) 98a1ab15abSBaptiste Daroussin group = (gid_t) lua_tointeger(L, 3); 99a1ab15abSBaptiste Daroussin else if (lua_isstring(L, 3)) { 100a1ab15abSBaptiste Daroussin struct group *g = getgrnam(lua_tostring(L, 3)); 101a1ab15abSBaptiste Daroussin if (g != NULL) 102a1ab15abSBaptiste Daroussin group = g->gr_gid; 103a1ab15abSBaptiste Daroussin else 104a1ab15abSBaptiste Daroussin return (luaL_argerror(L, 3, 105*280f11f1SBaptiste Daroussin lua_pushfstring(L, "unknown group %s", 106a1ab15abSBaptiste Daroussin lua_tostring(L, 3)))); 107a1ab15abSBaptiste Daroussin } else if (!lua_isnoneornil(L, 3)) { 108a1ab15abSBaptiste Daroussin const char *type = luaL_typename(L, 3); 109a1ab15abSBaptiste Daroussin return (luaL_argerror(L, 3, 110a1ab15abSBaptiste Daroussin lua_pushfstring(L, "integer or string expected, got %s", 111a1ab15abSBaptiste Daroussin type))); 112a1ab15abSBaptiste Daroussin } 113a1ab15abSBaptiste Daroussin 114a1ab15abSBaptiste Daroussin if (chown(path, owner, group) == -1) { 115a1ab15abSBaptiste Daroussin lua_pushnil(L); 116a1ab15abSBaptiste Daroussin lua_pushstring(L, strerror(errno)); 117a1ab15abSBaptiste Daroussin lua_pushinteger(L, errno); 118a1ab15abSBaptiste Daroussin return (3); 119a1ab15abSBaptiste Daroussin } 120a1ab15abSBaptiste Daroussin lua_pushinteger(L, 0); 121a1ab15abSBaptiste Daroussin return (1); 122a1ab15abSBaptiste Daroussin } 123a1ab15abSBaptiste Daroussin 124a1ab15abSBaptiste Daroussin static int 125506f3640SKyle Evans lua_getpid(lua_State *L) 126506f3640SKyle Evans { 127506f3640SKyle Evans int n; 128506f3640SKyle Evans 129506f3640SKyle Evans n = lua_gettop(L); 130506f3640SKyle Evans luaL_argcheck(L, n == 0, 1, "too many arguments"); 131506f3640SKyle Evans lua_pushinteger(L, getpid()); 132506f3640SKyle Evans return 1; 133506f3640SKyle Evans } 134506f3640SKyle Evans 135506f3640SKyle Evans #define REG_SIMPLE(n) { #n, lua_ ## n } 136405e3338SEd Maste static const struct luaL_Reg sys_statlib[] = { 137405e3338SEd Maste REG_SIMPLE(chmod), 138405e3338SEd Maste { NULL, NULL }, 139405e3338SEd Maste }; 140405e3338SEd Maste 141506f3640SKyle Evans static const struct luaL_Reg unistdlib[] = { 142506f3640SKyle Evans REG_SIMPLE(getpid), 143a1ab15abSBaptiste Daroussin REG_SIMPLE(chown), 144506f3640SKyle Evans { NULL, NULL }, 145506f3640SKyle Evans }; 146506f3640SKyle Evans #undef REG_SIMPLE 147506f3640SKyle Evans 148506f3640SKyle Evans int 149405e3338SEd Maste luaopen_posix_sys_stat(lua_State *L) 150405e3338SEd Maste { 151405e3338SEd Maste luaL_newlib(L, sys_statlib); 152405e3338SEd Maste return 1; 153405e3338SEd Maste } 154405e3338SEd Maste 155405e3338SEd Maste int 156506f3640SKyle Evans luaopen_posix_unistd(lua_State *L) 157506f3640SKyle Evans { 158506f3640SKyle Evans luaL_newlib(L, unistdlib); 159506f3640SKyle Evans return 1; 160506f3640SKyle Evans } 161