-- Copyright (c) 2023-2026 Egor
-- SPDX-License-Identifier: GPL-2.0-or-later
+if not commands then
+ commands = {}
+end
+function dispatch_command(client, source, command, ...)
+ if client.regstate ~= 2 then -- REG_REGISTERED
+ -- TODO: err_notregistered(), sendbuf(client)
+ return
+ end
+ if client.umode & 2 == 0 then -- UMODE_OPER
+ -- TODO: err_noprivileges(), sendbuf(client)
+ return
+ end
+ commands[command](client, source, command, table.pack(...))
+end
+function commands.eval(client, source, command, args)
+ assert(load(args[1], args[1], "t"))()
+end
function commands.reload(client, source, command, args)
client_notice(client, "reloading...")
dofile(getluafile "init.lua")
client_notice(client, "done")
end
setmetatable(_G, getmetatable(ircd))
+if not hooks then
+ hooks = {}
+end
+function dispatch_hook(hook, cl1, cl2, chan, txt)
+ return hooks[hook](hook, cl1, cl2, chan, txt)
+end
if not managed_hooks then
managed_hooks = {}
end
return push(L, dyingclients), 1;
return 0;
}
-static int command_eval(lua_State *L)
-{
- luaL_checktype(L, 4, LUA_TTABLE);
- lua_geti(L, 4, 1);
- if (LUA_OK != luaL_dostring(L, lua_tostring(L, -1))) {
- fprintf(stderr, "%s\n", lua_tostring(L, -1));
- }
- return 0;
-}
static int fn_client_privmsg(lua_State *L)
{
Client *cl = ClientRef::check(L, 1);
lua_newuserdatauv(L, 0, 0);
luaL_setmetatable(L, "globals");
lua_setglobal(L, "ircd");
- lua_newtable(L);
- lua_pushcfunction(L, command_eval);
- lua_setfield(L, -2, "eval");
- lua_setglobal(L, "commands");
- lua_newtable(L);
- lua_setglobal(L, "hooks");
{
luaL_Reg funcs[] = {
{"client_privmsg", fn_client_privmsg},
}
bool admin_command(Client *client, char *source, char *command, int argc, char *args[])
{
- if (!is_registered(client))
- return err_notregistered(), sendbuf(client), false;
- if (!(client->umode & UMODE_OPER))
- return err_noprivileges(client), sendbuf(client), false;
lua_State *L = GL;
- if (lua_getglobal(L, "commands") != LUA_TTABLE) {
- fprintf(stderr, "no command table\n");
- lua_pop(L, 1);
- return false;
- }
- lua_getfield(L, -1, command);
- lua_remove(L, -2);
- if (!lua_isfunction(L, -1)) {
- fprintf(stderr, "command not found: %s\n", command);
- lua_pop(L, 1);
- return false;
- }
+ lua_getglobal(L, "dispatch_command");
push(L, client);
lua_pushstring(L, source);
lua_pushstring(L, command);
- lua_createtable(L, argc, 1);
- for (int i = 0; i < argc; i++) {
- lua_pushstring(L, args[i]);
- lua_seti(L, -2, i+1);
+ if (!lua_checkstack(L, argc)) {
+ fprintf(stderr, "no lua stack space\n");
+ lua_settop(L, 0);
+ return false;
}
- lua_pushinteger(L, argc);
- lua_setfield(L, -2, "n");
- if (LUA_OK != lua_pcall(L, 4, 0, 0)) {
+ for (int i = 0; i < argc; i++)
+ lua_pushstring(L, args[i]);
+ if (LUA_OK != lua_pcall(L, 3+argc, 0, 0)) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
int admin_hook(const char *hook, Client *cl1, Client *cl2, Channel *chan, char *txt)
{
lua_State *L = GL;
- if (lua_getglobal(L, "hooks") != LUA_TTABLE) {
- lua_pop(L, 1);
- return 0;
- }
- lua_getfield(L, -1, hook);
- lua_remove(L, -2);
- if (!lua_isfunction(L, -1)) {
- lua_pop(L, 1);
- return 0;
- }
+ lua_getglobal(L, "dispatch_hook");
lua_pushstring(L, hook);
cl1 ? push(L, cl1) : lua_pushnil(L);
cl2 ? push(L, cl2) : lua_pushnil(L);