cortav  makeshim.lua at [35ea3c5797]

File tool/makeshim.lua artifact cea771ab78 part of check-in 35ea3c5797


-- [ʞ] tools/makeshim.lua
--  ~ lexi hale <lexi@hale.su>
--  🄯 AGPLv3
--  ? this program creates a C source file embedding
--    cortav, for the purposes of standalone deployment
--    without a lua interpreter, or for the purposes of
--    giving cortav extra privileges

local includes = [[
#include <lua.h>
#include <lauxlib.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
extern int luaL_openlibs(lua_State* l);
]]


local main = [[
int main(int argc, char** argv) {
	lua_State* l = luaL_newstate();
	luaL_openlibs(l);

	// pass arguments thru to lua
	lua_newtable(l);
	for(size_t i = 0; i < argc; ++i) {
		lua_pushstring(l,argv[i]);
		lua_rawseti(l, -2, i);
	}
	lua_setglobal(l, "arg");

	// load and run our payload
	int e = luaL_loadbufferx(l, ct_bytecode, sizeof(ct_bytecode), "cortav", "b");
	if (e != LUA_OK) {
		printf("some kind of error idk fam\n");
		return -1;
	}

	if (lua_pcall(l, 0, 0, 0) != LUA_OK) {
		size_t len;
		const char* msg = luaL_tolstring(l, -1, &len);
		if (isatty(2)) {
			fprintf(stderr, "\33[31;1m(fatal)\33[m %.*s\n", (int)len, msg);
		} else {
			fprintf(stderr, "(fatal) %.*s\n", (int)len, msg);
		}
	};

	// normal termination is by the os.exit() call
	return -1;
}
]]

local function setfile(i, dflt, mode)
	if arg[i] and arg[i] ~= '' then
		local fn = io.open(arg[i], mode)
		if fn then
			return fn
		end
		io.stderr:write('(' .. arg[0]..' fatal) cannot open file '..arg[i])
	end
	return dflt
end

local src = setfile(1, io.stdin, "rb")
local dest = setfile(2, io.stdout, "w")

local cstr = {}
local strtpl = [[static char ct_bytecode [%u] = {
%s
};]]

local bytes = {}

local bn = 1
local len = 0
while true do
	local byte = src:read(1)
	if not byte then break end
	local str = tostring(byte:byte(1))..','
	-- make sure our source file is parseable by
	-- a compliant C compiler
	local strl = string.len(str)
	if len + strl >= 4095 then
		len = 0
		bytes[bn]='\n'
		bn = bn + 1
	end
	len = len + strl
	bytes[bn] = str
	bn = bn + 1
end

local lines = {
	includes;
	strtpl:format(#bytes, table.concat(bytes));
	main;
}

dest:write(table.concat(lines, '\n'))