1 /*- 2 * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "lua.h" 32 #include "lauxlib.h" 33 #include "lstd.h" 34 #include "lutils.h" 35 #include "bootstrap.h" 36 37 static int 38 lua_perform(lua_State *L) 39 { 40 int argc; 41 char **argv; 42 int res = 1; 43 44 if (parse(&argc, &argv, luaL_checkstring(L, 1)) == 0) { 45 res = interp_builtin_cmd(argc, argv); 46 free(argv); 47 } 48 lua_pushinteger(L, res); 49 50 return 1; 51 } 52 53 static int 54 lua_getchar(lua_State *L) 55 { 56 57 lua_pushinteger(L, getchar()); 58 return 1; 59 } 60 61 static int 62 lua_ischar(lua_State *L) 63 { 64 65 lua_pushboolean(L, ischar()); 66 return 1; 67 } 68 69 static int 70 lua_gets(lua_State *L) 71 { 72 char buf[129]; 73 74 ngets(buf, 128); 75 lua_pushstring(L, buf); 76 return 1; 77 } 78 79 static int 80 lua_time(lua_State *L) 81 { 82 83 lua_pushinteger(L, time(NULL)); 84 return 1; 85 } 86 87 static int 88 lua_delay(lua_State *L) 89 { 90 91 delay((int)luaL_checknumber(L, 1)); 92 return 0; 93 } 94 95 static int 96 lua_getenv(lua_State *L) 97 { 98 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); 99 100 return 1; 101 } 102 103 static int 104 lua_setenv(lua_State *L) 105 { 106 const char *key, *val; 107 108 key = luaL_checkstring(L, 1); 109 val = luaL_checkstring(L, 2); 110 lua_pushinteger(L, setenv(key, val, 1)); 111 112 return 1; 113 } 114 115 static int 116 lua_unsetenv(lua_State *L) 117 { 118 const char *ev; 119 120 ev = luaL_checkstring(L, 1); 121 lua_pushinteger(L, unsetenv(ev)); 122 123 return 1; 124 } 125 126 static int 127 lua_printc(lua_State *L) 128 { 129 int status; 130 ssize_t l; 131 const char *s = luaL_checklstring(L, 1, &l); 132 133 status = (printf("%s", s) == l); 134 135 return status; 136 } 137 138 static int 139 lua_openfile(lua_State *L) 140 { 141 const char *str; 142 143 if (lua_gettop(L) != 1) { 144 lua_pushnil(L); 145 return 1; 146 } 147 str = lua_tostring(L, 1); 148 149 FILE * f = fopen(str, "r"); 150 if (f != NULL) { 151 FILE ** ptr = (FILE**)lua_newuserdata(L, sizeof(FILE**)); 152 *ptr = f; 153 } else 154 lua_pushnil(L); 155 return 1; 156 } 157 158 static int 159 lua_closefile(lua_State *L) 160 { 161 FILE ** f; 162 if (lua_gettop(L) != 1) { 163 lua_pushboolean(L, 0); 164 return 1; 165 } 166 167 f = (FILE**)lua_touserdata(L, 1); 168 if (f != NULL && *f != NULL) { 169 lua_pushboolean(L, fclose(*f) == 0 ? 1 : 0); 170 *f = NULL; 171 } else 172 lua_pushboolean(L, 0); 173 174 return 1; 175 } 176 177 static int 178 lua_readfile(lua_State *L) 179 { 180 FILE **f; 181 size_t size, r; 182 char * buf; 183 184 if (lua_gettop(L) < 1 || lua_gettop(L) > 2) { 185 lua_pushnil(L); 186 lua_pushinteger(L, 0); 187 return 2; 188 } 189 190 f = (FILE**)lua_touserdata(L, 1); 191 192 if (f == NULL || *f == NULL) { 193 lua_pushnil(L); 194 lua_pushinteger(L, 0); 195 return 2; 196 } 197 198 if (lua_gettop(L) == 2) 199 size = (size_t)lua_tonumber(L, 2); 200 else 201 size = (*f)->size; 202 203 204 buf = (char*)malloc(size); 205 r = fread(buf, 1, size, *f); 206 lua_pushlstring(L, buf, r); 207 free(buf); 208 lua_pushinteger(L, r); 209 210 return 2; 211 } 212 213 #define REG_SIMPLE(n) { #n, lua_ ## n } 214 static const struct luaL_Reg loaderlib[] = { 215 REG_SIMPLE(delay), 216 REG_SIMPLE(getenv), 217 REG_SIMPLE(perform), 218 REG_SIMPLE(printc), 219 REG_SIMPLE(setenv), 220 REG_SIMPLE(time), 221 REG_SIMPLE(unsetenv), 222 { NULL, NULL }, 223 }; 224 225 static const struct luaL_Reg iolib[] = { 226 { "close", lua_closefile }, 227 REG_SIMPLE(getchar), 228 REG_SIMPLE(gets), 229 REG_SIMPLE(ischar), 230 { "open", lua_openfile }, 231 { "read", lua_readfile }, 232 { NULL, NULL }, 233 }; 234 #undef REG_SIMPLE 235 236 void 237 register_utils(lua_State *L) 238 { 239 luaL_newlib(L, loaderlib); 240 lua_setglobal(L, "loader"); 241 luaL_newlib(L, iolib); 242 lua_setglobal(L, "io"); 243 } 244