interpreter.c 32.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Copyright 2016, CZ.NIC z.s.p.o. (http://www.nic.cz/)
 *
 * This file is part of the turris updater.
 *
 * Updater is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * Updater is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Updater.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "interpreter.h"
21
#include "util.h"
22
#include "events.h"
23
#include "journal.h"
24 25
#include "md5.h"
#include "sha256.h"
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
26
#include "locks.h"
27
#include "arguments.h"
28
#include "picosat.h"
29 30 31 32 33 34

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <string.h>
#include <stdbool.h>
35
#include <stdarg.h>
36
#include <inttypes.h>
37
#include <errno.h>
38 39
#include <sys/stat.h>
#include <sys/types.h>
40
#include <sys/wait.h>
41 42 43
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
44 45 46

// The name used in lua registry to store stuff
#define REGISTRY_NAME "libupdater"
47

48
static const char *crash_file = "/tmp/updater_crash.log";
49

50
// From the embed file, lua things that are auto-loaded
51
extern struct file_index_element lautoload[];
52

53 54
struct interpreter {
	lua_State *state;
55
	struct events *events;
56 57
};

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
static int err_handler(lua_State *L) {
	/*
	 * Call stacktraceplus.stacktrace(msg). But in a safe way,
	 * if it doesn't work, just return msg. This may happen
	 * before the stacktraceplus library is loaded.
	 */
	int top = lua_gettop(L);
	/*
	 * Make sure we have enough space for:
	 * • stacktraceplus
	 * • stacktrace function
	 * • its parameter
	 * • another copy of the error message.
	 *
	 * The manual isn't clear if the old stack is reused for
	 * the error handler, or a new one is provided. So just
	 * expect the worst.
	 */
	if (!lua_checkstack(L, 4))
		return 1; // Reuse the provided param as a result
78
	lua_getfield(L, LUA_GLOBALSINDEX, "c_pcall_error_handler");
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
	if (!lua_isfunction(L, -1))
		goto FAIL;
	lua_pushvalue(L, top);
	int result = lua_pcall(L, 1, 1, 0);
	if (result)
		goto FAIL;
	// The result is on the top. Just return it.
	return 1;
FAIL:	// In case we fail to provide the error message
	// Copy the original message
	lua_pushvalue(L, top);
	return 1;
}

static int push_err_handler(lua_State *L) {
	luaL_checkstack(L, 1, "Not enough space to push error handler");
	lua_pushcfunction(L, err_handler);
	return lua_gettop(L);
}

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
static const char *interpreter_error_result(lua_State *L) {
	// There's an error on top of the stack
	if (lua_istable(L, -1)) {
		lua_getfield(L, -1, "trace");
		const char *trace = lua_tostring(L, -1);
		if (trace) {
			DBG("%s", trace);
			if (!dump2file(crash_file, trace))
				WARN("Crash report of stack trace dump failed.");
		} // Else just print message, we are probably missing trace
		lua_pop(L, 1);
		lua_getfield(L, -1, "msg");
	}
	const char *errmsg = lua_tostring(L, -1);
	return errmsg;
}

116 117
static int lua_log(lua_State *L) {
	int nargs = lua_gettop(L);
118
	ASSERT_MSG(nargs >= 1, "Not enough arguments passed to log()");
119
	enum log_level level = log_level_get(lua_tostring(L, 1));
120 121 122 123 124 125
	int depth = luaL_checkinteger(L, 2); // Depth to ignore and report upper location
	if (depth < 0)
		return luaL_error(L, "Second argument mustn't be less then zero");
	struct lua_Debug ldebug;
	lua_getstack(L, depth + 1, &ldebug); // get informations about caller
	lua_getinfo(L, "Sln", &ldebug);
126
	size_t sum = 1;
127 128 129
	size_t sizes[nargs - 2];
	const char *strs[nargs - 2];
	for (int i = 3; i <= nargs; i ++) {
130 131 132 133 134
		if (lua_isnil(L, i))
			strs[i - 3] = "<nil>";
		else if((strs[i - 3] = lua_tostring(L, i)) == NULL)
			// If it is not nil nor string or number, it is function or table so too complex just for simple log function
			strs[i - 3] = "<complex-type>";
135 136
		sizes[i - 3] = strlen(strs[i - 3]);
		sum += sizes[i - 3];
137 138 139
	}
	char *message = alloca(sum);
	size_t pos = 0;
140
	for (size_t i = 0; i < (unsigned)nargs - 2; i ++) {
141 142 143 144
		memcpy(message + pos, strs[i], sizes[i]);
		pos += sizes[i];
	}
	message[pos] = '\0';
145 146
	char *file = aprintf("%s.lua", ldebug.source);
	log_internal(level, file, ldebug.currentline, ldebug.name ? ldebug.name : "Globals", "%s", message);
147 148 149
	return 0;
}

150 151 152 153 154 155
static int lua_state_dump(lua_State *L) {
	const char *state = luaL_checkstring(L, 1);
	state_dump(state);
	return 0;
}

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
/*
 * Put a value from the stack (at index) into our own table in the registry.
 * Return the index under which it is stored in there. The returned value allocated
 * on the heap, you must free it yourself.
 */
static char *register_value(lua_State *L, int index) {
	// Make sure we don't skew the index by placing other stuff onto the stack
	lua_pushvalue(L, index);
	lua_getfield(L, LUA_REGISTRYINDEX, REGISTRY_NAME);
	// We expect this won't wrap around for the lifetime of the program
	static uint64_t id = 0;
	const size_t max_len = 26; // 21 characters is the max length of uint64_t in decimal, val- is 4, 1 for '\0'
	char *result = malloc(max_len);
	snprintf(result, max_len, "val-%" PRIu64, id ++);
	lua_pushvalue(L, -2);
	lua_setfield(L, -2, result);
	// Pop the table and the original copy of the value
	lua_pop(L, 2);
	return result;
}

/*
 * Extract named value from registry table onto the top of stack.
 * Remove it from the registry table. Free the name.
 */
static void extract_registry_value(lua_State *L, char *name) {
	// Get the registry table
	lua_getfield(L, LUA_REGISTRYINDEX, REGISTRY_NAME);
	// Get the value
	lua_getfield(L, -1, name);
186 187 188 189
	// Delete the value the from registry table
	lua_pushnil(L);
	// The table is now at -3, because we added the result and the nil on top of stack
	lua_setfield(L, -3, name);
190 191 192 193 194 195 196 197 198 199 200 201 202 203
	// Remove the registry table
	lua_remove(L, -2);

	free(name);
}

struct lua_command_data {
	struct lua_State *L;
	char *terminated_callback;
	char *postfork_callback;
};

// Extract pointer of userdata from the lua registry
static void *extract_registry(lua_State *L, const char *name) {
204 205
	lua_getfield(L, LUA_REGISTRYINDEX, REGISTRY_NAME);
	lua_getfield(L, -1, name);
206 207
	ASSERT(lua_islightuserdata(L, -1));
	void *result = lua_touserdata(L, -1);
208
	lua_pop(L, 2);
209 210 211
	return result;
}

212 213 214
// Name of the wait_id meta table
#define WAIT_ID_META "WAIT_ID_META"

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
static void command_terminated(struct wait_id id __attribute__((unused)), void *data, int status, enum command_kill_status killed, size_t out_size, const char *out, size_t err_size, const char *err) {
	struct lua_command_data *lcd = data;
	struct lua_State *L = lcd->L;
	ASSERT(L);
	// This may be called from C code with a dirty stack
	luaL_checkstack(L, 6, "Not enough stack space to call command callback");
	int handler = push_err_handler(L);
	if (lcd->postfork_callback) {
		/*
		 * This already happened in the child. But we need to free
		 * resources ‒ remove it from the registry table.
		 */
		extract_registry_value(L, lcd->postfork_callback);
		lua_pop(L, 1);
	}
	// Get the lua function.
	ASSERT(lcd->terminated_callback);
	extract_registry_value(L, lcd->terminated_callback);
	/*
	 * We terminated the command, we won't need it any more.
	 * Make sure we don't leak even if the lua throws or whatever.
	 */
	free(lcd);
	// Push the rest of parameters here
239
	lua_pushinteger(L, WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
240 241 242 243 244 245 246 247 248 249 250 251 252 253
	const char *ks = NULL;
	switch (killed) {
#define KS(NAME) case CK_##NAME: ks = #NAME; break
		KS(TERMINATED);
		KS(TERMED);
		KS(KILLED);
		KS(SIGNAL_OTHER);
#undef KS
	}
	ASSERT(ks);
	lua_pushstring(L, ks);
	lua_pushlstring(L, out, out_size);
	lua_pushlstring(L, err, err_size);
	int result = lua_pcall(L, 4, 0, handler);
254
	ASSERT_MSG(!result, "%s", interpreter_error_result(L));
255 256 257 258 259 260 261 262 263 264 265
}

static void command_postfork(void *data) {
	struct lua_command_data *lcd = data;
	struct lua_State *L = lcd->L;
	ASSERT(L);
	// This would be called from within the lua_run_command, no need to allocate more stack
	if (lcd->postfork_callback) {
		int handler = push_err_handler(L);
		extract_registry_value(L, lcd->postfork_callback);
		int result = lua_pcall(L, 0, 0, handler);
266
		ASSERT_MSG(!result, "%s", interpreter_error_result(L));
267 268 269 270
	}
	// We don't worry about freeing memory here. We're going to exec just in a while.
}

271 272 273 274 275 276 277 278 279
static void do_flush(lua_State *L, const char *handle) {
	lua_getfield(L, LUA_GLOBALSINDEX, "io");
	lua_getfield(L, -1, handle);
	lua_getfield(L, -1, "flush");
	lua_pushvalue(L, -2);
	lua_call(L, 1, 0);
	lua_pop(L, 2);
}

280 281 282 283 284 285 286 287 288
// Push the provided wait ID onto the top of the lua stack
static void push_wid(lua_State *L, const struct wait_id *id) {
	struct wait_id *lid = lua_newuserdata(L, sizeof *lid);
	*lid = *id;
	// Set meta table. Empty one, but make sure we can recognize our data.
	luaL_newmetatable(L, WAIT_ID_META);
	lua_setmetatable(L, -2);
}

289
static int lua_run_generic(lua_State *L, bool utils) {
290 291 292 293
	// Flush the lua output (it seems to buffered separately)
	do_flush(L, "stdout");
	do_flush(L, "stderr");
	// Extract the parameters. There's a lot of them.
294 295 296 297 298 299 300 301 302
	luaL_checktype(L, 1, LUA_TFUNCTION);
	int pf_cback_type = lua_type(L, 2);
	if (pf_cback_type != LUA_TNIL && pf_cback_type != LUA_TFUNCTION)
		return luaL_error(L, "The 2nd argument of run_command must be either function or nil");
	if (!lua_isnil(L, 3) && !lua_isstring(L, 3))
		return luaL_error(L, "The 3rd argument of run_command is a string input or nil");
	int term_timeout = luaL_checkinteger(L, 4);
	int kill_timeout = luaL_checkinteger(L, 5);
	const char *command = luaL_checkstring(L, 6);
303 304 305 306
	if (utils) {
		DBG("Util command %s", command);
	} else
		DBG("Command %s", command);
307 308 309 310
	// The rest of the args are args for the command ‒ get them into an array
	const size_t arg_count = lua_gettop(L) - 6;
	const char *args[arg_count + 1];
	for (int i = 6; i < lua_gettop(L); i ++)
311
		DBG("Arg %s", args[i - 6] = luaL_checkstring(L, i + 1));
312 313 314 315 316 317 318 319 320 321 322 323
	args[arg_count] = NULL;
	// Data for the callbacks. It will get freed there.
	struct lua_command_data *data = malloc(sizeof *data);
	data->L = L;
	data->terminated_callback = register_value(L, 1);
	data->postfork_callback = lua_isnil(L, 2) ? NULL : register_value(L, 2);
	struct events *events = extract_registry(L, "events");
	ASSERT(events);
	size_t input_size = 0;
	const char *input = NULL;
	if (lua_isstring(L, 3))
		input = lua_tolstring(L, 3, &input_size);
324 325 326 327 328
	struct wait_id id;
	if (utils)
		id = run_util_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, command, args);
	else
		id = run_command_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, command, args);
329
	push_wid(L, &id);
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
330
	// Return 1 value ‒ the wait_id
331 332 333
	return 1;
}

334 335 336 337 338 339 340 341
static int lua_run_command(lua_State *L) {
	return lua_run_generic(L, false);
}

static int lua_run_util(lua_State *L) {
	return lua_run_generic(L, true);
}

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
struct lua_download_data {
	lua_State *L;
	char *callback;
};

static void download_callback(struct wait_id id __attribute__((unused)), void *data, int status, size_t out_size, const char *out) {
	struct lua_download_data *d = data;
	struct lua_State *L = d->L;
	ASSERT(L);
	// This may be called from C code with a dirty stack
	luaL_checkstack(L, 4, "Not enough stack space to call download callback");
	int handler = push_err_handler(L);
	// Get the lua function.
	ASSERT(d->callback);
	extract_registry_value(L, d->callback);
	/*
	 * We terminated the command, we won't need it any more.
	 * Make sure we don't leak even if the lua throws or whatever.
	 */
	free(d);
	lua_pushinteger(L, status);
	lua_pushlstring(L, out, out_size);
	int result = lua_pcall(L, 2, 0, handler);
365
	ASSERT_MSG(!result, "%s", interpreter_error_result(L));
366 367 368 369 370 371 372 373
}

static int lua_download(lua_State *L) {
	// Flush the lua output (it seems to buffered separately)
	do_flush(L, "stdout");
	do_flush(L, "stderr");
	// Extract params
	luaL_checktype(L, 1, LUA_TFUNCTION);
374
	int pcount = lua_gettop(L);
375 376
	const char *url = luaL_checkstring(L, 2);
	const char *cacert = NULL;
377
	if (pcount >= 3 && !lua_isnil(L, 3))
378 379
		cacert = luaL_checkstring(L, 3);
	const char *crl = NULL;
380
	if (pcount >= 4 && !lua_isnil(L, 4))
381
		crl = luaL_checkstring(L, 4);
382
	bool ssl = lua_toboolean(L, 5);
383 384 385 386 387 388 389
	// Handle the callback
	struct lua_download_data *data = malloc(sizeof *data);
	data->L = L;
	data->callback = register_value(L, 1);
	// Run the download
	struct events *events = extract_registry(L, "events");
	ASSERT(events);
390
	struct wait_id id = download(events, download_callback, data, url, cacert, crl, ssl);
391 392 393 394 395
	// Return the ID
	push_wid(L, &id);
	return 1;
}

Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
396 397 398 399
static int lua_events_wait(lua_State *L) {
	// All the parameters here are the wait_id userdata. We need to put them into an array.
	size_t event_count = lua_gettop(L);
	struct wait_id ids[event_count];
400 401 402
	for (size_t i = 1; i <= event_count; i ++)
		// Check each one is the wait_id we provided
		memcpy(&ids[i - 1], luaL_checkudata(L, i, WAIT_ID_META), sizeof ids[i - 1]);
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
403 404 405 406 407 408
	struct events *events = extract_registry(L, "events");
	events_wait(events, event_count, ids);
	// Nothing returned
	return 0;
}

409 410 411 412
static int lua_mkdtemp(lua_State *L) {
	int param_count = lua_gettop(L);
	if (param_count > 1)
		return luaL_error(L, "Too many parameters to mkdtemp: %d", param_count);
413 414 415
	const char *base_dir = getenv("TMPDIR");
	if (!base_dir)
		base_dir = "/tmp";
416
	if (param_count && !lua_isnil(L, 1))
417 418 419 420 421 422 423 424 425 426 427 428 429
		base_dir = luaL_checkstring(L, 1);
	char *template = aprintf("%s/updater-XXXXXX", base_dir);
	char *result = mkdtemp(template);
	if (result) {
		lua_pushstring(L, result);
		return 1;
	} else {
		lua_pushnil(L);
		lua_pushstring(L, strerror(errno));
		return 2;
	}
}

430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
static int lua_chdir(lua_State *L) {
	int param_count = lua_gettop(L);
	if (param_count != 1)
		return luaL_error(L, "chdir expects 1 parameter");
	const char *path = luaL_checkstring(L, 1);
	int result = chdir(path);
	if (result == -1)
		return luaL_error(L, "chdir to %s: %s", path, strerror(errno));
	return 0;
}

static int lua_getcwd(lua_State *L) {
	const char *result = NULL;
	// An arbitrary length.
	size_t s = 16;
	while (!result) {
		s *= 2;
		char *buf = alloca(s);
		result = getcwd(buf, s);
		if (!result && errno != ERANGE)
			return luaL_error(L, "getcwd: %s", strerror(errno));
	}
	lua_pushstring(L, result);
	return 1;
}

456 457 458 459 460 461 462 463 464 465
static int lua_mkdir(lua_State *L) {
	const char *dir = luaL_checkstring(L, 1);
	// TODO: Make the mask configurable
	int result = mkdir(dir, 0777);
	if (result == -1)
		return luaL_error(L, "mkdir '%s' failed: %s", dir, strerror(errno));
	// No results if it was successfull
	return 0;
}

466 467 468 469 470 471 472 473 474 475 476 477
struct mv_result_data {
	char *err;
	int status;
};

static void mv_result(struct wait_id id __attribute__((unused)), void *data, int status, enum command_kill_status killed __attribute__((unused)), size_t out_size __attribute__((unused)), const char *output __attribute__((unused)), size_t err_size __attribute__((unused)), const char *err) {
	struct mv_result_data *mv_result_data = data;
	mv_result_data->status = WTERMSIG(status);
	if (status)
		mv_result_data->err = strdup(err);
}

478 479 480
static int lua_move(lua_State *L) {
	const char *old = luaL_checkstring(L, 1);
	const char *new = luaL_checkstring(L, 2);
481 482 483 484 485 486 487 488 489 490 491 492 493 494
	/*
	 * TODO:
	 * We need to support cross-device move. But that one is a hell
	 * to implement (because it might be a symlink, block or character
	 * device, we need to support file permissions, etc. We use
	 * external mv for now instead, we may want to reconsider later.
	 *
	 * Also, musl seems to have a bug of not overwriting one symlink by
	 * another, which can cause strange errors, including not booting
	 * up the kernel.
	 */
	struct events *events = extract_registry(L, "events");
	ASSERT(events);
	struct mv_result_data mv_result_data = { .err = NULL };
495
	struct wait_id id = run_util(events, mv_result, NULL, &mv_result_data, 0, NULL, -1, -1, "mv", "-f", old, new, (const char *)NULL);
496 497
	events_wait(events, 1, &id);
	if (mv_result_data.status) {
498
		lua_pushfstring(L, "Failed to move '%s' to '%s': %s (ecode %d)", old, new, mv_result_data.err, mv_result_data.status);
499 500
		free(mv_result_data.err);
		return lua_error(L);
501 502 503 504
	}
	return 0;
}

505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
static const char *stat2str(const struct stat *buf) {
	switch (buf->st_mode & S_IFMT) {
		case S_IFSOCK:
			return "s";
		case S_IFLNK:
			return "l";
		case S_IFREG:
			return "r";
		case S_IFBLK:
			return "b";
		case S_IFDIR:
			return "d";
		case S_IFCHR:
			return "c";
		case S_IFIFO:
			return "f";
	}
	return "?";
}

525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
// Get the type of file refered by the dirent.
static const char *get_dirent_type(DIR *d, struct dirent *ent) {
	switch (ent->d_type) {
		case DT_BLK:
			return "b";
		case DT_CHR:
			return "c";
		case DT_DIR:
			return "d";
		case DT_FIFO:
			return "f";
		case DT_LNK:
			return "l";
		case DT_REG:
			return "r";
		case DT_SOCK:
			return "s";
		default: // DT_UNKNOWN
			// The file system might not have this info in dir, try again with stat
			break;
	}
546
	// OK, we didn't find out here, try again with stat
547 548 549 550 551 552
	struct stat buf;
	int result = fstatat(dirfd(d), ent->d_name, &buf, AT_SYMLINK_NOFOLLOW);
	if (result == -1) {
		ERROR("fstatat failed on %s: %s", ent->d_name, strerror(errno));
		return "?";
	}
553
	return stat2str(&buf);
554 555
}

556 557 558 559 560 561 562
static int lua_ls(lua_State *L) {
	const char *dir = luaL_checkstring(L, 1);
	DIR *d = opendir(dir);
	if (!d)
		return luaL_error(L, "Could not read directory %s: %s", dir, strerror(errno));
	struct dirent *ent;
	lua_newtable(L);
563
	errno = 0;
564
	while ((ent = readdir(d))) {
565 566
		// Skip the . and .. directories
		if (strcmp(ent->d_name, "..") && strcmp(ent->d_name, ".")) {
567
			lua_pushstring(L, get_dirent_type(d, ent));
568 569
			lua_setfield(L, -2, ent->d_name);
		}
570
		errno = 0;
571 572 573 574 575 576 577 578 579 580
	}
	int old_errno = errno;
	int result = closedir(d);
	if (old_errno)
		return luaL_error(L, "Could not read directory entity of %s: %s", dir, strerror(old_errno));
	if (result == -1)
		return luaL_error(L, "Failed to close directory %s: %s", dir, strerror(errno));
	return 1;
}

581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
struct perm_def {
	mode_t mask;
	size_t pos;
	char letter;
};

/*
 * Note that some of these are on the same position. They are
 * ordered so that the last matching wins, producing the desired
 * result.
 */
static const struct perm_def perm_defs[] = {
	{ S_IRUSR, 0, 'r' },
	{ S_IWUSR, 1, 'w' },
	{ S_IXUSR, 2, 'x' },
	{ S_IRGRP, 3, 'r' },
	{ S_IWGRP, 4, 'w' },
	{ S_IXGRP, 5, 'x' },
	{ S_IROTH, 6, 'r' },
	{ S_IWOTH, 7, 'w' },
	{ S_IXOTH, 8, 'x' },
	{ S_ISVTX, 8, 't' },
	{ S_ISVTX | S_IXOTH, 8, 'T' },
	{ S_ISGID, 5, 'S' },
	{ S_ISGID | S_IXGRP, 5, 's' },
	{ S_ISUID, 2, 'S' },
	{ S_ISUID | S_IXUSR, 2, 's' }
};

static const char *perm2str(struct stat *buf) {
	static char perm[9];
	memset(perm, '-', sizeof perm);
	for (size_t i = 0; i < sizeof perm_defs / sizeof *perm_defs; i ++) {
		if ((buf->st_mode & perm_defs[i].mask) == perm_defs[i].mask) // All the bits are set according to the mask
			perm[perm_defs[i].pos] = perm_defs[i].letter;
	}
	return perm;
}

620
static int stat_lstat(lua_State *L, bool use_lstat) {
621 622
	const char *fname = luaL_checkstring(L, 1);
	struct stat buf;
623
	int result;
624
	if (use_lstat)
625 626 627
		result = lstat(fname, &buf);
	else
		result = stat(fname, &buf);
628 629 630 631 632 633 634 635
	if (result == -1) {
		if (errno == ENOENT)
			// No result, because the file does not exist
			return 0;
		else
			return luaL_error(L, "Failed to stat '%s': %s", fname, strerror(errno));
	}
	lua_pushstring(L, stat2str(&buf));
636 637
	lua_pushstring(L, perm2str(&buf));
	return 2;
638 639
}

640 641 642 643 644 645 646 647
static int lua_stat(lua_State *L) {
	return stat_lstat(L, false);
}

static int lua_lstat(lua_State *L) {
	return stat_lstat(L, true);
}

648
static int lua_sync(lua_State *L __attribute__((unused))) {
649
	DBG("Sync");
650 651 652 653
	sync();
	return 0;
}

654 655 656 657 658 659 660 661 662 663
static int lua_setenv(lua_State *L) {
	const char *name = luaL_checkstring(L, 1);
	const char *value = luaL_checkstring(L, 2);
	int result = setenv(name, value, 1);
	if (result) {
		return luaL_error(L, "Failed to set env %s = %s", name, value, strerror(errno));
	}
	return 0;
}

664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
static void push_hex(lua_State *L, const uint8_t *buffer, size_t size) {
	char result[2 * size];
	for (size_t i = 0; i < size; i ++)
		sprintf(result + 2 * i, "%02hhx", buffer[i]);
	lua_pushlstring(L, result, 2 * size);
}

static int lua_md5(lua_State *L) {
	size_t len;
	const char *buffer = luaL_checklstring(L, 1, &len);
	uint8_t result[MD5_DIGEST_SIZE];
	md5_buffer(buffer, len, result);
	push_hex(L, result, sizeof result);
	return 1;
}

static int lua_sha256(lua_State *L) {
	size_t len;
	const char *buffer = luaL_checklstring(L, 1, &len);
	uint8_t result[SHA256_DIGEST_SIZE];
	sha256_buffer(buffer, len, result);
	push_hex(L, result, sizeof result);
	return 1;
}

689 690 691 692 693 694 695 696
static int lua_reexec(lua_State *L) {
	size_t args_c = lua_gettop(L);
	const char *args[args_c];
	size_t i;
	for (i = 0; i < args_c; i++) {
		args[i] = luaL_checkstring(L, i + 1);
	}
	reexec(args_c, (char**) args);
697 698 699
	return 0;
}

700 701 702 703 704 705 706 707 708
// Stores pointer to internal files used as uri.
static const struct file_index_element *uriinternal;

static int lua_uri_internal_get(lua_State *L) {
	int param_count = lua_gettop(L);
	if (param_count > 1)
		return luaL_error(L, "Too many parameters to uri_internal_get: %d", param_count);
	const char *name = luaL_checkstring(L, 1);
	if (!uriinternal)
709
		return luaL_error(L, "Internal uri is not supported.", name);
710 711
	const struct file_index_element *file = index_element_find(uriinternal, name);
	if (!file)
712
		return luaL_error(L, "No internal with name: %s", name);
713 714 715 716
	lua_pushlstring(L, (const char *)file->data, file->size);
	return 1;
}

717 718 719 720 721 722
static int lua_system_reboot(lua_State *L) {
	bool stick = lua_toboolean(L, 1);
	system_reboot(stick);
	return 0;
}

723 724 725 726 727
static int lua_get_updater_version(lua_State *L) {
	lua_pushstring(L, UPDATER_VERSION);
	return 1;
}

728 729 730 731 732 733 734
extern bool state_log_enabled; // defined in util.c

static int lua_state_log_enabled(lua_State *L) {
	lua_pushboolean(L, state_log_enabled);
	return 1;
}

735 736 737 738 739 740
struct injected_func {
	int (*func)(lua_State *);
	const char *name;
};

static const struct injected_func injected_funcs[] = {
741
	{ lua_log, "log" },
742
	{ lua_state_log_enabled, "state_log_enabled" },
743
	{ lua_state_dump, "state_dump" },
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
744
	{ lua_run_command, "run_command" },
745
	{ lua_run_util, "run_util" },
746
	{ lua_download, "download" },
747
	{ lua_events_wait, "events_wait" },
748 749 750 751 752
	/*
	 * Note: watch_cancel is not provided, because it would be hell to
	 * manage the dynamically allocated memory correctly and there doesn't
	 * seem to be a need for them at this moment.
	 */
753 754
	{ lua_mkdtemp, "mkdtemp" },
	{ lua_chdir, "chdir" },
755 756 757
	{ lua_getcwd, "getcwd" },
	{ lua_mkdir, "mkdir" },
	{ lua_move, "move" },
758
	{ lua_ls, "ls" },
759
	{ lua_stat, "stat" },
760
	{ lua_lstat, "lstat" },
761
	{ lua_sync, "sync" },
762
	{ lua_setenv, "setenv" },
763
	{ lua_md5, "md5" },
764
	{ lua_sha256, "sha256" },
765
	{ lua_reexec, "reexec" },
766
	{ lua_uri_internal_get, "uri_internal_get" },
767 768
	{ lua_system_reboot, "system_reboot" },
	{ lua_get_updater_version, "get_updater_version" }
769 770
};

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
#ifdef COVERAGE
// From the embed file. Coverage lua code.
extern struct file_index_element lcoverage[];

static int interpreter_coverage_dump(lua_State *L) {
	char *out_dir = getenv("COVERAGEDIR");
	if (!out_dir) {
		WARN("COVERAGEDIR variable not specified. Skipping coverage dump");
		return 0;
	}
	DBG("Executing coverage data dump.");
	int handler = push_err_handler(L);
	lua_getfield(L, LUA_GLOBALSINDEX, "coverage");
	lua_getfield(L, -1, "dump"); // called function
	lua_pushstring(L, out_dir); // argument
	if (lua_pcall(L, 1, 0, handler))
		ERROR("Coverage data dump failed: %s", interpreter_error_result(L));
	lua_pop(L, 1); // pop coverage module from stack
	lua_remove(L, handler);
	return 0;
}

static void interpreter_load_coverage(struct interpreter *interpreter) {
	lua_State *L = interpreter->state;
	DBG("Initializing Lua code coverage");
	if (!interpreter_include(interpreter, (const char *) lcoverage->data, lcoverage->size, "coverage")) {
		lua_getfield(L, LUA_GLOBALSINDEX, "coverage"); // get this module
		lua_newuserdata(L, 1); // push to stack dummy user data. They are freed by Lua it self not our code.
		lua_newtable(L); // new meta table for user data
		lua_pushcfunction(L, interpreter_coverage_dump);
		lua_setfield(L, -2, "__gc"); // set function to to new table
		lua_setmetatable(L, -2); // set new table as user data meta table
		lua_setfield(L, -2, "gc_udata"); // Set dummy user data to coverage.gc_udata
		lua_pop(L, 1); // Pop coverage module from stack
	} else
		WARN("Loading of Lua coverage code failed.");
}
#endif

810 811
struct interpreter *interpreter_create(struct events *events, const struct file_index_element *uriinter) {
	uriinternal = uriinter;
812
	struct interpreter *result = malloc(sizeof *result);
813
	lua_State *L = luaL_newstate();
814
	*result = (struct interpreter) {
815 816
		.state = L,
		.events = events
817
	};
818
	luaL_openlibs(L);
819 820 821 822 823 824 825 826
	// Create registry for our needs and fill it with some data
	lua_newtable(L);
	lua_pushlightuserdata(L, result);
	lua_setfield(L, -2, "interpreter");
	lua_pushlightuserdata(L, events);
	lua_setfield(L, -2, "events");
	lua_setfield(L, LUA_REGISTRYINDEX, REGISTRY_NAME);
	// Insert bunch of functions
827 828 829 830 831
	for (size_t i = 0; i < sizeof injected_funcs / sizeof *injected_funcs; i ++) {
		DBG("Injecting function no %zu %s/%p", i, injected_funcs[i].name, injected_funcs[i].name);
		lua_pushcfunction(L, injected_funcs[i].func);
		lua_setglobal(L, injected_funcs[i].name);
	}
832 833
	// Some binary embedded modules
	journal_mod_init(L);
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
834
	locks_mod_init(L);
835
	picosat_mod_init(L);
836 837 838
#ifdef COVERAGE
	interpreter_load_coverage(result);
#endif
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
	return result;
}

struct reader_data {
	const char *chunk;
	size_t length;
	bool used;
};

const char *reader(lua_State *L __attribute__((unused)), void *data_raw, size_t *size) {
	struct reader_data *data = data_raw;
	if (data->used) {
		*size = 0;
		return NULL;
	} else {
		*size = data->length;
		data->used = true;
		return data->chunk;
	}
}

const char *interpreter_include(struct interpreter *interpreter, const char *code, size_t length, const char *src) {
861 862
	lua_State *L = interpreter->state;
	ASSERT(L);
863
	// We don't know how dirty stack we get here
864
	luaL_checkstack(L, 4, "Can't create space for interpreter_include");
865 866
	if (!length) // It is a null-terminated string, compute its length
		length = strlen(code);
867 868
	push_err_handler(L);
	int result = lua_load(L, reader, &(struct reader_data) {
869 870 871 872 873
		.chunk = code,
		.length = length
	}, src);
	if (result)
		// There's been an error. Extract it (top of the stack).
874
		return interpreter_error_result(L);
875 876 877 878 879 880
	/*
	 * The stack:
	 * • … (unknown stuff from before)
	 * • The error handler (-2)
	 * • The chunk to call (-1)
	 */
881
	result = lua_pcall(L, 0, 1, -2);
882
	// Remove the error handler
883
	lua_remove(L, -2);
884
	if (result)
885
		return interpreter_error_result(L);
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
	bool has_result = true;
	if (lua_isnil(L, -1)) {
		/*
		 * In case the module returned nil, use true instead, to properly
		 * imitate require in what is put into package.loaded.
		 */
		lua_pop(L, 1);
		lua_pushboolean(L, 1);
		has_result = false;
	}
	// Store it into package.loaded
	lua_getfield(L, LUA_GLOBALSINDEX, "package");
	lua_getfield(L, -1, "loaded");
	/*
	 * The stack:
	 * • ̣… (unknown stuff from before)
	 * • The result of load (-3)
	 * • package (-2)
	 * • package.loaded (-1)
	 */
	/*
	 * Check if the table is already there and don't override it if so.
	 * This is the case of module() in the loaded stuff.
	 */
	lua_getfield(L, -1, src);
	bool is_table = lua_istable(L, -1);
	lua_pop(L, 1);
	if (!is_table) {
		// Get a copy of the result on top
		lua_pushvalue(L, -3);
		// Move the top into the table
		lua_setfield(L, -2, src);
	}
	// Drop the two tables from top of the stack, leave the result there
	lua_pop(L, 2);
	if (has_result)
		// Store the result (pops it from the stack)
		lua_setfield(L, LUA_GLOBALSINDEX, src);
	else
		lua_pop(L, 1);
926
	return NULL;
927 928
}

929
const char *interpreter_autoload(struct interpreter *interpreter) {
930
	for (struct file_index_element *el = lautoload; el->name; el ++) {
931 932 933
		const char *underscore = rindex(el->name, '_');
		// Use the part after the last underscore as the name
		const char *name = underscore ? underscore + 1 : el->name;
934
		DBG("Including module %s", name);
935
		const char *err = interpreter_include(interpreter, (const char *) el->data, el->size, name);
936 937 938 939 940 941
		if (err)
			return err;
	}
	return NULL;
}

942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
static void lookup(lua_State *L, char **name, char **end) {
	/*
	 * Look-up a value in the table on the top of the stack
	 * and move in the string being parsed. Also remove the
	 * old table.
	 */
	// Terminate the string (replace the separator)
	**end = '\0';
	// Do the lookup
	lua_getfield(L, -1, *name);
	// Move in the string
	*name = *end + 1;
	// And get rid of the old one
	lua_remove(L, -2);
}

958
const char *interpreter_call(struct interpreter *interpreter, const char *function, size_t *result_count, const char *param_spec, ...) {
959 960 961 962 963 964 965
	// Get a read-write version of the function string.
	size_t flen = strlen(function);
	char *f = alloca(flen + 1);
	strcpy(f, function);
	lua_State *L = interpreter->state;
	// Clear the stack
	lua_pop(L, lua_gettop(L));
966
	int handler = push_err_handler(L);
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
	/*
	 * Make sure the index 1 always contains the
	 * table we want to look up in. We start at the global
	 * scope.
	 */
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	char *pos;
	while ((pos = strchr(f, '.'))) {
		// Look up the new table in the current one, moving the position
		lookup(L, &f, &pos);
	}
	size_t nparams = 0;
	if ((pos = strchr(f, ':'))) {
		// It is a method. Look up the table first
		lookup(L, &f, &pos);
		// Look up the function in the table
		lua_getfield(L, -1, f);
		// set „self“ to the table we looked up in
		lua_pushvalue(L, -2);
		nparams = 1;
	} else
		lua_getfield(L, -1, f);
	// Drop the table we looked up the function inside
	lua_remove(L, -2 - nparams);
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
	// Reserve space for the parameters. One letter in param_spec is one param.
	size_t spec_len = strlen(param_spec);
	luaL_checkstack(L, spec_len, "Couldn't grow the LUA stack for parameters");
	nparams += spec_len;
	va_list args;
	va_start(args, param_spec);
	for (; *param_spec; param_spec ++) {
		switch (*param_spec) {
#define CASE(TYPE, SIGN, FUN) \
			case SIGN: { \
				TYPE x = va_arg(args, TYPE); \
				lua_push##FUN(L, x); \
				break; \
			}
			// Represent bool as int, because of C type promotions
1006
			// cppcheck-suppress va_end_missing (false positive: look just below the for cycle)
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
			CASE(int, 'b', boolean);
			case 'n': // No param here
				lua_pushnil(L);
				break;
			CASE(int, 'i', integer);
			CASE(const char *, 's', string);
			case 'S': { // binary string, it has 2 parameters
				const char *s = va_arg(args, const char *);
				size_t len = va_arg(args, size_t);
				lua_pushlstring(L, s, len);
				break;
			}
			CASE(double, 'f', number);
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
			case 'r': {
				const char *s = va_arg(args, const char *);
				// Get the registry table
				lua_getfield(L, LUA_REGISTRYINDEX, REGISTRY_NAME);
				// Get the value
				lua_getfield(L, -1, s);
				// Remove the registry table. This way we added only the extracted value.
				lua_remove(L, -2);
				break;
			}
1030
			default:
1031
				DIE("Unknown type specifier '%c' passed", *param_spec);
1032 1033 1034 1035
#undef CASE
		}
	}
	va_end(args);
1036 1037
	int result = lua_pcall(L, nparams, LUA_MULTRET, handler);
	lua_remove(L, handler);
1038
	if (result) {
1039
		return interpreter_error_result(L);
1040
	}
1041 1042
	if (result_count)
		*result_count = lua_gettop(L);
1043 1044 1045 1046
	return NULL;
}

int interpreter_collect_results(struct interpreter *interpreter, const char *spec, ...) {
1047 1048 1049 1050 1051 1052
	lua_State *L = interpreter->state;
	size_t top = lua_gettop(L);
	size_t pos = 0;
	va_list args;
	va_start(args, spec);
	for (; *spec; spec ++) {
1053 1054
		if (pos >= top) {
			va_end(args);
1055
			return pos;
1056
		}
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
		switch (*spec) {
			case 'b': {
				bool *b = va_arg(args, bool *);
				*b = lua_toboolean(L, pos + 1);
				break;
			}
			case 'i':
				if (lua_isnumber(L, pos + 1)) {
					int *i = va_arg(args, int *);
					*i = lua_tointeger(L, pos + 1);
				} else
					return pos;
				break;
			case 'n':
				if (!lua_isnil(L, pos + 1))
					return pos;
				// Fall through to skipping the the '-' case
			case '-':
				// Just skipping the position
				break;
			case 's':
				if (lua_isstring(L, pos + 1)) {
					const char **s = va_arg(args, const char **);
					*s = lua_tostring(L, pos + 1);
				} else
					return pos;
				break;
			case 'S':
				if (lua_isstring(L, pos + 1)) {
					const char **s = va_arg(args, const char **);
					size_t *l = va_arg(args, size_t *);
					*s = lua_tolstring(L, pos + 1, l);
				} else
					return pos;
				break;
			case 'f':
				if (lua_isnumber(L, pos + 1)) {
					double *d = va_arg(args, double *);
					*d = lua_tonumber(L, pos + 1);
				} else
					return pos;
				break;
1099 1100 1101 1102 1103
			case 'r': {
				char **name = va_arg(args, char **);
				*name = register_value(L, pos + 1);
				break;
			}
1104
			default:
1105
				DIE("Invalid type specifier '%c' passed", *spec);
1106 1107 1108 1109 1110
		}
		pos ++;
	}
	va_end(args);
	return -1;
1111 1112
}

1113 1114 1115 1116 1117 1118
void interpreter_registry_release(struct interpreter *interpreter, char *name) {
	extract_registry_value(interpreter->state, name);
	// Get rid of the value on top of the stack as well
	lua_pop(interpreter->state, 1);
}

1119
void interpreter_destroy(struct interpreter *interpreter) {
1120
	ASSERT(interpreter->state);
1121 1122 1123 1124
	lua_close(interpreter->state);
	interpreter->state = NULL;
	free(interpreter);
}