/* * rhctl * * Copyright (C) 2009-2014 Christian Pointner * * This file is part of rhctl. * * rhctl 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 * any later version. * * rhctl 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 rhctl. If not, see . */ #include #include #include #include #include #include "datatypes.h" #include "l_cmd.h" #include "options.h" #include "command_queue.h" #include "client_list.h" #include "log.h" #include "utils.h" int cmd_fd; read_buffer_t cmd_buffer; static int l_cmd_getfd(lua_State *L) { if(!lua_istable(L, -1)) luaL_error(L, "can't retreive signal fd"); lua_pushliteral(L, "fd"); lua_gettable(L, -2); return 1; } static int l_cmd_dirty(lua_State *L) { lua_pushboolean(L, 0); return 1; } static int l_cmd_init(lua_State *L) { lua_newtable(L); lua_pushliteral(L, "fd"); lua_pushinteger(L, cmd_fd); lua_settable(L, -3); lua_pushliteral(L, "getfd"); lua_pushcfunction(L, l_cmd_getfd); lua_settable(L, -3); lua_pushliteral(L, "dirty"); lua_pushcfunction(L, l_cmd_dirty); lua_settable(L, -3); return 1; } // gets called by nonblock_recvline for every complete message static int cmd_recv_data(lua_State* L) { int ret = 0; for(;;) { ret = recv(cmd_fd, &cmd_buffer.buf[cmd_buffer.offset], 1, 0); if(!ret) return 2; if(ret == -1 && errno == EAGAIN) return 0; else if(ret < 0) break; if(cmd_buffer.buf[cmd_buffer.offset] == '\n') { cmd_buffer.buf[cmd_buffer.offset] = 0; lua_pushstring(L, (char *)(cmd_buffer.buf)); ret = lua_pcall(L, 1, 1, 0); if(ret) { const char* err_str = luaL_checkstring(L, -1); switch(ret) { case LUA_ERRRUN: log_printf(ERROR, "lua_pcall(cmd_callback) runtime error: %s", err_str); break; case LUA_ERRMEM: log_printf(ERROR, "lua_pcall(cmd_callback) malloc error: %s", err_str); break; case LUA_ERRERR: log_printf(ERROR, "lua_pcall(cmd_callback) error at error handler function: %s", err_str); break; } return -1; } ret = lua_tointeger(L, 1); cmd_buffer.offset = 0; break; } cmd_buffer.offset++; if(cmd_buffer.offset >= sizeof(cmd_buffer.buf)) { log_printf(DEBUG, "string too long cmd_fd"); cmd_buffer.offset = 0; return 0; } } return ret; } static int l_cmd_recv_data(lua_State* L) { int ret = cmd_recv_data(L); lua_pushinteger(L, ret); return 1; } static int l_cmd_send_string(lua_State* L) { int ret = send_string(cmd_fd, luaL_checkstring(L,1)); if (ret > 0) do { ret = write(cmd_fd, "\n", 1); } while(!ret || (ret == -1 && errno == EINTR)); if(ret > 0) ret = 0; lua_pushinteger(L, ret); return 1; } static const struct luaL_reg cmd_funcs [] = { { "init", l_cmd_init }, { "recv_data", l_cmd_recv_data }, { "send_string", l_cmd_send_string }, { NULL, NULL } }; LUALIB_API int luaopen_cmd(lua_State *L) { luaL_register(L, LUA_CMDLIBNAME, cmd_funcs); return 1; }