diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | core/modulemanager.lua | 19 | ||||
-rw-r--r-- | core/s2smanager.lua | 2 | ||||
-rw-r--r-- | core/sessionmanager.lua | 2 | ||||
-rw-r--r-- | net/server.lua | 4 | ||||
-rw-r--r-- | net/xmppclient_listener.lua | 19 | ||||
-rw-r--r-- | net/xmppserver_listener.lua | 30 | ||||
-rw-r--r-- | plugins/mod_posix.lua | 50 | ||||
-rwxr-xr-x | prosody | 7 | ||||
-rw-r--r-- | util-src/Makefile | 9 | ||||
-rw-r--r-- | util-src/pposix.c | 92 | ||||
-rw-r--r-- | util/logger.lua | 18 |
12 files changed, 202 insertions, 58 deletions
@@ -12,9 +12,10 @@ INSTALLEDCONFIG = $(SYSCONFDIR) INSTALLEDMODULES = $(PREFIX)/lib/prosody/modules INSTALLEDDATA = $(DATADIR) -all: prosody.install prosody.cfg.lua.install util/encodings.so util/hashes.so +all: prosody.install prosody.cfg.lua.install + $(MAKE) -C util-src install -install: prosody.install prosody.cfg.lua.install util/encodings.so util/encodings.so +install: prosody.install prosody.cfg.lua.install util/encodings.so util/encodings.so util/pposix.so install -d $(BIN) $(CONFIG) $(MODULES) $(SOURCE) $(DATA) install -d $(CONFIG)/certs install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util @@ -39,6 +40,9 @@ util/encodings.so: util/hashes.so: $(MAKE) install -C util-src +util/pposix.so: + $(MAKE) install -C util-src + prosody.install: prosody sed "s|^CFG_SOURCEDIR=.*;$$|CFG_SOURCEDIR='$(INSTALLEDSOURCE)';|; \ s|^CFG_CONFIGDIR=.*;$$|CFG_CONFIGDIR='$(INSTALLEDCONFIG)';|; \ diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 1382e227..3c27e7a0 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -44,7 +44,7 @@ module "modulemanager" local api = {}; -- Module API container -local modulemap = {}; +local modulemap = { ["*"] = {} }; local stanza_handlers = multitable_new(); local handler_info = {}; @@ -67,19 +67,23 @@ function load(host, module_name, config) if not (host and module_name) then return nil, "insufficient-parameters"; end - local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua"); - if not mod then - log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); - return nil, err; - end if not modulemap[host] then modulemap[host] = {}; elseif modulemap[host][module_name] then log("warn", "%s is already loaded for %s, so not loading again", module_name, host); return nil, "module-already-loaded"; + elseif modulemap["*"][module_name] then + return nil, "global-module-already-loaded"; end + + local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua"); + if not mod then + log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); + return nil, err; + end + local _log = logger.init(host..":"..module_name); local api_instance = setmetatable({ name = module_name, host = host, config = config, _log = _log, log = function (self, ...) return _log(...); end }, { __index = api }); @@ -93,7 +97,8 @@ function load(host, module_name, config) return nil, ret; end - modulemap[host][module_name] = mod; + -- Use modified host, if the module set one + modulemap[api_instance.host][module_name] = mod; return true; end diff --git a/core/s2smanager.lua b/core/s2smanager.lua index 5eb28b50..ae834a9c 100644 --- a/core/s2smanager.lua +++ b/core/s2smanager.lua @@ -94,7 +94,7 @@ function new_incoming(conn) local session = { conn = conn, type = "s2sin_unauthed", direction = "incoming" }; if true then session.trace = newproxy(true); - getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; print("s2s session got collected, now "..open_sessions.." s2s sessions are allocated") end; + getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; end; end open_sessions = open_sessions + 1; local w, log = conn.write, logger_init("s2sin"..tostring(conn):match("[a-f0-9]+$")); diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 74a17fe5..a597e724 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -52,7 +52,7 @@ function new_session(conn) local session = { conn = conn, priority = 0, type = "c2s_unauthed", conntime = gettime() }; if true then session.trace = newproxy(true); - getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; print("Session got collected, now "..open_sessions.." sessions are allocated") end; + getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; end; end open_sessions = open_sessions + 1; log("info", "open sessions now: ".. open_sessions); diff --git a/net/server.lua b/net/server.lua index 55afcf3f..5c129753 100644 --- a/net/server.lua +++ b/net/server.lua @@ -798,10 +798,6 @@ end loop = function( ) -- this is the main loop of the program --signal_set( "hub", "run" ) repeat - --[[print(readlen, writelen) - for _, s in ipairs(readlist) do print("R:", tostring(s)) end - for _, s in ipairs(writelist) do print("W:", tostring(s)) end - out_put("select()"..os.time())]] local read, write, err = socket_select( readlist, writelist, 1 ) -- 1 sec timeout, nice for timers for i, socket in ipairs( write ) do -- send data waiting in writequeues local handler = socketlist[ socket ] diff --git a/net/xmppclient_listener.lua b/net/xmppclient_listener.lua index 22af2de4..c2326a55 100644 --- a/net/xmppclient_listener.lua +++ b/net/xmppclient_listener.lua @@ -47,7 +47,7 @@ function stream_callbacks.error(session, error, data) end end -local function handleerr(err) print("Traceback:", err, debug.traceback()); end +local function handleerr(err) log("error", "Traceback[c2s]:", err, debug.traceback()); end function stream_callbacks.handlestanza(a, b) xpcall(function () core_process_stanza(a, b) end, handleerr); end @@ -116,25 +116,16 @@ function xmppclient.listener(conn, data) -- Logging functions -- - local mainlog, log = log; - do - local conn_name = "c2s"..tostring(conn):match("[a-f0-9]+$"); - log = logger.init(conn_name); - end - local print = function (...) log("info", t_concatall({...}, "\t")); end - session.log = log; - - print("Client connected"); + local conn_name = "c2s"..tostring(conn):match("[a-f0-9]+$"); + session.log = logger.init(conn_name); + + session.log("info", "Client connected"); session.reset_stream = session_reset_stream; session.close = session_close; session_reset_stream(session); -- Initialise, ready for use - -- TODO: Below function should be session,stanza - and xmlhandlers should use :method() notation to call, - -- this will avoid the useless indirection we have atm - -- (I'm on a mission, no time to fix now) - -- Debug version -- --local function handleerr(err) print("Traceback:", err, debug.traceback()); end --session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end diff --git a/net/xmppserver_listener.lua b/net/xmppserver_listener.lua index bdd3948d..e4816b1e 100644 --- a/net/xmppserver_listener.lua +++ b/net/xmppserver_listener.lua @@ -39,6 +39,11 @@ function stream_callbacks.error(session, error, data) end end +local function handleerr(err) log("error", "Traceback[s2s]:", err, debug.traceback()); end +function stream_callbacks.handlestanza(a, b) + xpcall(function () core_process_stanza(a, b) end, handleerr); +end + local connlisteners_register = require "net.connlisteners".register; local t_insert = table.insert; @@ -113,25 +118,17 @@ function xmppserver.listener(conn, data) -- Logging functions -- - local mainlog, log = log; - do - local conn_name = "s2sin"..tostring(conn):match("[a-f0-9]+$"); - log = logger.init(conn_name); - end - local print = function (...) log("info", t_concatall({...}, "\t")); end - session.log = log; - - print("Incoming s2s connection"); + + local conn_name = "s2sin"..tostring(conn):match("[a-f0-9]+$"); + session.log = logger.init(conn_name); + + session.log("info", "Incoming s2s connection"); session.reset_stream = session_reset_stream; session.close = session_close; session_reset_stream(session); -- Initialise, ready for use - -- FIXME: Below function should be session,stanza - and xmlhandlers should use :method() notation to call, - -- this will avoid the useless indirection we have atm - -- (I'm on a mission, no time to fix now) - -- Debug version -- -- local function handleerr(err) print("Traceback:", err, debug.traceback()); end -- session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end @@ -164,11 +161,8 @@ function xmppserver.register_outgoing(conn, session) session.reset_stream = session_reset_stream; session_reset_stream(session); -- Initialise, ready for use - -- FIXME: Below function should be session,stanza - and xmlhandlers should use :method() notation to call, - -- this will avoid the useless indirection we have atm - -- (I'm on a mission, no time to fix now) - local function handleerr(err) print("Traceback:", err, debug.traceback()); end - session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end + --local function handleerr(err) print("Traceback:", err, debug.traceback()); end + --session.stanza_dispatch = function (stanza) return select(2, xpcall(function () return core_process_stanza(session, stanza); end, handleerr)); end end connlisteners_register("xmppserver", xmppserver); diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua new file mode 100644 index 00000000..8dc4c77d --- /dev/null +++ b/plugins/mod_posix.lua @@ -0,0 +1,50 @@ + +local pposix = assert(require "util.pposix"); + +local config_get = require "core.configmanager".get; +local logger_set = require "util.logger".setwriter; + +module.host = "*"; -- we're a global module + +if not config_get("*", "core", "no_daemonize") then + local function daemonize_server() + local logwriter; + + local logfilename = config_get("*", "core", "log"); + if logfilename then + local logfile = io.open(logfilename, "a+"); + if logfile then + local write, format, flush = logfile.write, string.format, logfile.flush; + logwriter = function (name, level, message, ...) + if ... then + write(logfile, name, "\t", level, "\t", format(message, ...), "\n"); + else + write(logfile, name, "\t" , level, "\t", message, "\n"); + end + flush(logfile); + end; + end + else + log("debug", "No logging specified, will continue with default"); + end + + local ok, ret = pposix.daemonize(); + if not ok then + log("error", "Failed to daemonize: %s", ret); + elseif ret and ret > 0 then + log("info", "Daemonized to pid %d", ret); + os.exit(0); + else + log("info", "Successfully daemonized"); + + if logwriter then + local ok, ret = logger_set(logwriter); + if not ok then + log("error", "Couldn't set new log output: %s", ret); + end + end + + end + end + module:add_event_hook("server-starting", daemonize_server); +end @@ -112,7 +112,6 @@ local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" en local _mkdir = {} function mkdir(path) path = path:gsub("/", path_separator); - --print("mkdir",path); local x = io.popen("mkdir \""..path.."\" 2>&1"):read("*a"); end function encode(s) return s and (s:gsub("%W", function (c) return string.format("%%%x", c:byte()); end)); end @@ -138,11 +137,7 @@ eventmanager.fire_event("server-starting"); -- setup error handling -setmetatable(_G, { __index = function (t, k) print("WARNING: ATTEMPT TO READ A NIL GLOBAL!!!", k); error("Attempt to read a non-existent global. Naughty boy.", 2); end, __newindex = function (t, k, v) print("ATTEMPT TO SET A GLOBAL!!!!", tostring(k).." = "..tostring(v)); error("Attempt to set a global. Naughty boy.", 2); end }) --]][][[]][]; - -local protected_handler = function (conn, data, err) local success, ret = pcall(handler, conn, data, err); if not success then print("ERROR on "..tostring(conn)..": "..ret); conn:close(); end end; -local protected_disconnect = function (conn, err) local success, ret = pcall(disconnect, conn, err); if not success then print("ERROR on "..tostring(conn).." disconnect: "..ret); conn:close(); end end; - +setmetatable(_G, { __index = function (t, k) error("Attempt to read a non-existent global '"..k.."'", 2); end, __newindex = function (t, k, v) error("Attempt to set a global: "..tostring(k).." = "..tostring(v), 2); end }); local global_ssl_ctx = config.get("*", "core", "ssl"); if global_ssl_ctx then diff --git a/util-src/Makefile b/util-src/Makefile index 4aedec40..18e1e78d 100644 --- a/util-src/Makefile +++ b/util-src/Makefile @@ -9,9 +9,9 @@ OPENSSL_LIB?=crypto -all: encodings.so hashes.so +all: encodings.so hashes.so pposix.so -install: encodings.so hashes.so +install: encodings.so hashes.so pposix.so install *.so ../util/ @@ -29,4 +29,9 @@ hashes.o: hashes.c gcc $(CFLAGS) -I$(LUA_INCDIR) -c -o hashes.o hashes.c hashes.so: hashes.o export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc $(LFLAGS) -o hashes.so hashes.o -L/usr/local/lib -llua$(LUA_SUFFIX) -lcrypto -lssl + +pposix.o: pposix.c + gcc $(CFLAGS) -I$(LUA_INCDIR) -c -o pposix.o pposix.c +pposix.so: pposix.o + export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc $(LFLAGS) -o pposix.so pposix.o -L/usr/local/lib -llua$(LUA_SUFFIX) diff --git a/util-src/pposix.c b/util-src/pposix.c new file mode 100644 index 00000000..5e15ed76 --- /dev/null +++ b/util-src/pposix.c @@ -0,0 +1,92 @@ +/* Prosody IM v0.1 +-- Copyright (C) 2008 Matthew Wild +-- Copyright (C) 2008 Waqas Hussain +-- +-- This program 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 2 +-- of the License, or (at your option) any later version. +-- +-- This program 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 this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* pposix.c + POSIX support functions for Lua +*/ + +#include <stdlib.h> +#include <unistd.h> +#include <libgen.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "lua.h" + +static int daemonize(lua_State *L) +{ + + pid_t pid; + + if ( getppid() == 1 ) + { + lua_pushboolean(L, 0); + lua_pushstring(L, "already-daemonized"); + return 2; + } + + /* Attempt initial fork */ + if((pid = fork()) < 0) + { + /* Forking failed */ + lua_pushboolean(L, 0); + lua_pushstring(L, "fork-failed"); + return 2; + } + else if(pid != 0) + { + /* We are the parent process */ + lua_pushboolean(L, 1); + lua_pushnumber(L, pid); + return 2; + } + + /* and we are the child process */ + if(setsid() == -1) + { + /* We failed to become session leader */ + /* (we probably already were) */ + lua_pushboolean(L, 0); + lua_pushstring(L, "setsid-failed"); + return 2; + } + + /* Close stdin, stdout, stderr */ +/* close(0); + close(1); + close(2); +*/ + /* Final fork, use it wisely */ + if(fork()) + exit(0); + + /* Show's over, let's continue */ + lua_pushboolean(L, 1); + lua_pushnil(L); + return 2; +} + +int luaopen_util_pposix(lua_State *L) +{ + lua_newtable(L); + lua_pushcfunction(L, daemonize); + lua_setfield(L, -2, "daemonize"); + return 1; +}; diff --git a/util/logger.lua b/util/logger.lua index 82a7e110..f7ea187b 100644 --- a/util/logger.lua +++ b/util/logger.lua @@ -17,11 +17,9 @@ -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -- - - local format, rep = string.format, string.rep; local io_write = io.write; -local print = print; +local pcall = pcall; local debug = debug; local tostring = tostring; local math_max = math.max; @@ -42,6 +40,8 @@ end local sourcewidth = 20; +local outfunction = nil; + function init(name) --name = nil; -- While this line is not commented, will automatically fill in file/line number info sourcewidth = math_max(#name+2, sourcewidth); @@ -51,6 +51,9 @@ function init(name) local inf = debug.getinfo(3, 'Snl'); level = level .. ","..tostring(inf.short_src):match("[^/]*$")..":"..inf.currentline; end + + if outfunction then return outfunction(name, level, message, ...); end + if ... then io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", format(message, ...), "\n"); else @@ -59,4 +62,13 @@ function init(name) end end +function setwriter(f) + if not f then outfunction = nil; return true, nil; end + local ok, ret = pcall(f, "logger", "info", "Switched logging output successfully"); + if ok then + outfunction = f; + end + return ok, ret; +end + return _M; |