+function loop()
+ -- Error handler for errors that make it this far
+ local function catch_uncaught_error(err)
+ if type(err) == "string" and err:match("interrupted!$") then
+ return "quitting";
+ end
+
+ log("error", "Top-level error, please report:\n%s", tostring(err));
+ local traceback = debug.traceback("", 2);
+ if traceback then
+ log("error", "%s", traceback);
+ end
+
+ prosody.events.fire_event("very-bad-error", {error = err, traceback = traceback});
+ end
+
+ while select(2, xpcall(server.loop, catch_uncaught_error)) ~= "quitting" do
+ socket.sleep(0.2);
+ end
+end
+
+function cleanup()
+ log("info", "Shutdown status: Cleaning up");
+ prosody.events.fire_event("server-cleanup");
+
+ -- Ok, we're quitting I know, but we
+ -- need to do some tidying before we go :)
+ server.setquitting(false);
+
+ log("info", "Shutdown status: Closing all active sessions");
+ for hostname, host in pairs(hosts) do
+ log("debug", "Shutdown status: Closing client connections for %s", hostname)
+ if host.sessions then
+ local reason = { condition = "system-shutdown", text = "Server is shutting down" };
+ if prosody.shutdown_reason then
+ reason.text = reason.text..": "..prosody.shutdown_reason;
+ end
+ for username, user in pairs(host.sessions) do
+ for resource, session in pairs(user.sessions) do
+ log("debug", "Closing connection for %s@%s/%s", username, hostname, resource);
+ session:close(reason);
+ end
+ end
+ end
+
+ log("debug", "Shutdown status: Closing outgoing s2s connections from %s", hostname);
+ if host.s2sout then
+ for remotehost, session in pairs(host.s2sout) do
+ if session.close then
+ session:close("system-shutdown");
+ else
+ log("warn", "Unable to close outgoing s2s session to %s, no session:close()?!", remotehost);
+ end
+ end
+ end
+ end
+
+ log("info", "Shutdown status: Closing all server connections");
+ server.closeall();
+
+ server.setquitting(true);
+end
+
+-- Are you ready? :)
+-- These actions are in a strict order, as many depend on
+-- previous steps to have already been performed
+read_config();
+init_logging();
+sandbox_require();
+set_function_metatable();
+load_libraries();
+init_global_state();
+read_version();
+log("info", "Hello and welcome to Prosody version %s", prosody.version);
+log_dependency_warnings();
+load_secondary_libraries();
+init_data_store();
+init_global_protection();
+prepare_to_start();
+
+prosody.events.fire_event("server-started");
+
+loop();
+
+log("info", "Shutting down...");
+cleanup();
+prosody.events.fire_event("server-stopped");
+log("info", "Shutdown complete");