Merge from waqas
authorMatthew Wild <mwild1@gmail.com>
Sat, 6 Dec 2008 23:23:08 +0000 (23:23 +0000)
committerMatthew Wild <mwild1@gmail.com>
Sat, 6 Dec 2008 23:23:08 +0000 (23:23 +0000)
12 files changed:
Makefile
core/modulemanager.lua
core/s2smanager.lua
core/sessionmanager.lua
net/server.lua
net/xmppclient_listener.lua
net/xmppserver_listener.lua
plugins/mod_posix.lua [new file with mode: 0644]
prosody
util-src/Makefile
util-src/pposix.c [new file with mode: 0644]
util/logger.lua

index 0e17e1e4d603e054249af6018159d59a792902ad..606d92b07cf88c5a3e9f0e8b97c82a95fcef3c68 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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)';|; \
index 1382e227d6be5ef46d826aba2c2b14ed68451c03..3c27e7a05ced771bd935201f0a2f58cca2b1b9ac 100644 (file)
@@ -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
index 5eb28b50bbf678d6329c8fc58c573bd2c43bb134..ae834a9c31618583c781922cc4dd575bd304e650 100644 (file)
@@ -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]+$"));
index 74a17fe5a5b174361feed539f087f5f464ac5cde..a597e724ba90c13871f947e62b170b891395713f 100644 (file)
@@ -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);
index 55afcf3f777d5a90cf863047709ba3de7ca1ba13..5c129753f2e069d3939552b7f06b557790690662 100644 (file)
@@ -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 ]
index 22af2de4cf72fabe50fd6012f30ef18ed12558c5..c2326a55af33d867e116e0592fe7f7234709512d 100644 (file)
@@ -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
index bdd3948df08e6443b0b4293c64f83ac425ae867d..e4816b1ebe84a2dfaf8bf656c6115282749fc74c 100644 (file)
@@ -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 (file)
index 0000000..8dc4c77
--- /dev/null
@@ -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
diff --git a/prosody b/prosody
index 76b8162d84d46c79b8412cc5187c45e06f693648..042d0212816fdb017135e8dcdbc6b1e76e4d6cf6 100755 (executable)
--- a/prosody
+++ b/prosody
@@ -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
index 4aedec401756a484eb384a4d4de11d47044c41d1..18e1e78d34b8200df499d4607c69972e53c78bd5 100644 (file)
@@ -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 (file)
index 0000000..5e15ed7
--- /dev/null
@@ -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;
+};
index 82a7e110cb8b61815b671e315ed3bdc8c31dcd7a..f7ea187b04efb22db94e3120c0d18506bee664d9 100644 (file)
 -- 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;