-- [ʞ] 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>
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;
}
lua_call(l, 0, 0);
// 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 lines = {includes}
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
len = len + string.len(str)
if len >= 4096 then
len = 0
bytes[bn]='\n'
bn = bn + 1
end
bytes[bn] = str
bn = bn + 1
end
table.insert(lines, strtpl:format(#bytes, table.concat(bytes)))
table.insert(lines, main)
dest:write(table.concat(lines, '\n'))