529 end |
529 end |
530 end |
530 end |
531 config.set("*", "log", { { levels = { min = log_level or "info" }, to = "console" } }); |
531 config.set("*", "log", { { levels = { min = log_level or "info" }, to = "console" } }); |
532 end |
532 end |
533 |
533 |
|
534 local function check_posix() |
|
535 if prosody.platform ~= "posix" then return end |
|
536 |
|
537 local want_pposix_version = "0.4.0"; |
|
538 local have_pposix, pposix = pcall(require, "prosody.util.pposix"); |
|
539 |
|
540 if pposix._VERSION ~= want_pposix_version then |
|
541 print(string.format("Unknown version (%s) of binary pposix module, expected %s", |
|
542 tostring(pposix._VERSION), want_pposix_version)); |
|
543 os.exit(1); |
|
544 end |
|
545 if have_pposix and pposix then |
|
546 return pposix; |
|
547 end |
|
548 end |
|
549 |
534 function startup.switch_user() |
550 function startup.switch_user() |
535 -- Switch away from root and into the prosody user -- |
551 -- Switch away from root and into the prosody user -- |
536 -- NOTE: This function is only used by prosodyctl. |
552 -- NOTE: This function is only used by prosodyctl. |
537 -- The prosody process is built with the assumption that |
553 -- The prosody process is built with the assumption that |
538 -- it is already started as the appropriate user. |
554 -- it is already started as the appropriate user. |
539 |
555 |
540 local want_pposix_version = "0.4.0"; |
556 local pposix = check_posix() |
541 local have_pposix, pposix = pcall(require, "prosody.util.pposix"); |
557 if pposix then |
542 |
|
543 if have_pposix and pposix then |
|
544 if pposix._VERSION ~= want_pposix_version then |
|
545 print(string.format("Unknown version (%s) of binary pposix module, expected %s", |
|
546 tostring(pposix._VERSION), want_pposix_version)); |
|
547 os.exit(1); |
|
548 end |
|
549 prosody.current_uid = pposix.getuid(); |
558 prosody.current_uid = pposix.getuid(); |
550 local arg_root = prosody.opts.root; |
559 local arg_root = prosody.opts.root; |
551 if prosody.current_uid == 0 and config.get("*", "run_as_root") ~= true and not arg_root then |
560 if prosody.current_uid == 0 and config.get("*", "run_as_root") ~= true and not arg_root then |
552 -- We haz root! |
561 -- We haz root! |
553 local desired_user = config.get("*", "prosody_user") or "prosody"; |
562 local desired_user = config.get("*", "prosody_user") or "prosody"; |
669 for hostname in pairs(config.getconfig()) do |
678 for hostname in pairs(config.getconfig()) do |
670 prosody.hosts[hostname] = startup.make_host(hostname); |
679 prosody.hosts[hostname] = startup.make_host(hostname); |
671 end |
680 end |
672 end |
681 end |
673 |
682 |
|
683 function startup.posix_umask() |
|
684 if prosody.platform ~= "posix" then return end |
|
685 local pposix = require "prosody.util.pposix"; |
|
686 local umask = config.get("*", "umask") or "027"; |
|
687 pposix.umask(umask); |
|
688 end |
|
689 |
|
690 function startup.check_user() |
|
691 local pposix = check_posix(); |
|
692 if not pposix then return end |
|
693 -- Don't even think about it! |
|
694 if pposix.getuid() == 0 and not config.get("*", "run_as_root") then |
|
695 log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!"); |
|
696 log("error", "For more information on running Prosody as root, see https://prosody.im/doc/root"); |
|
697 prosody.shutdown("Refusing to run as root", 1); |
|
698 end |
|
699 end |
|
700 |
|
701 local function remove_pidfile() |
|
702 local pidfile = prosody.pidfile; |
|
703 if prosody.pidfile_handle then |
|
704 prosody.pidfile_handle:close(); |
|
705 os.remove(pidfile); |
|
706 prosody.pidfile, prosody.pidfile_handle = nil, nil; |
|
707 end |
|
708 end |
|
709 |
|
710 function startup.write_pidfile() |
|
711 local pposix = check_posix(); |
|
712 if not pposix then return end |
|
713 local lfs = require "lfs"; |
|
714 local stat = lfs.attributes; |
|
715 local pidfile = config.get("*", "pidfile") or nil; |
|
716 if not pidfile then return end |
|
717 pidfile = config.resolve_relative_path(prosody.paths.data, pidfile); |
|
718 local mode = stat(pidfile) and "r+" or "w+"; |
|
719 local pidfile_handle, err = io.open(pidfile, mode); |
|
720 if not pidfile_handle then |
|
721 log("error", "Couldn't write pidfile at %s; %s", pidfile, err); |
|
722 prosody.shutdown("Couldn't write pidfile", 1); |
|
723 else |
|
724 prosody.pidfile = pidfile; |
|
725 if not lfs.lock(pidfile_handle, "w") then -- Exclusive lock |
|
726 local other_pid = pidfile_handle:read("*a"); |
|
727 log("error", "Another Prosody instance seems to be running with PID %s, quitting", other_pid); |
|
728 prosody.pidfile_handle = nil; |
|
729 prosody.shutdown("Prosody already running", 1); |
|
730 else |
|
731 pidfile_handle:close(); |
|
732 pidfile_handle, err = io.open(pidfile, "w+"); |
|
733 if not pidfile_handle then |
|
734 log("error", "Couldn't write pidfile at %s; %s", pidfile, err); |
|
735 prosody.shutdown("Couldn't write pidfile", 1); |
|
736 else |
|
737 if lfs.lock(pidfile_handle, "w") then |
|
738 pidfile_handle:write(tostring(pposix.getpid())); |
|
739 pidfile_handle:flush(); |
|
740 prosody.pidfile_handle = pidfile_handle; |
|
741 end |
|
742 end |
|
743 end |
|
744 end |
|
745 prosody.events.add_handler("server-stopped", remove_pidfile); |
|
746 end |
|
747 |
|
748 local function remove_log_sinks() |
|
749 local lm = require "prosody.core.loggingmanager"; |
|
750 lm.register_sink_type("console", nil); |
|
751 lm.register_sink_type("stdout", nil); |
|
752 lm.reload_logging(); |
|
753 end |
|
754 |
|
755 function startup.posix_daemonize() |
|
756 if not prosody.opts.daemonize then return end |
|
757 local pposix = check_posix(); |
|
758 log("info", "Prosody is about to detach from the console, disabling further console output"); |
|
759 remove_log_sinks(); |
|
760 local ok, ret = pposix.daemonize(); |
|
761 if not ok then |
|
762 log("error", "Failed to daemonize: %s", ret); |
|
763 elseif ret and ret > 0 then |
|
764 os.exit(0); |
|
765 else |
|
766 log("info", "Successfully daemonized to PID %d", pposix.getpid()); |
|
767 end |
|
768 end |
|
769 |
674 function startup.hook_posix_signals() |
770 function startup.hook_posix_signals() |
675 if prosody.platform ~= "posix" then return end |
771 if prosody.platform ~= "posix" then return end |
676 local have_signal, signal = pcall(require, "prosody.util.signal"); |
772 local have_signal, signal = pcall(require, "prosody.util.signal"); |
677 if not have_signal then |
773 if not have_signal then |
678 log("warn", "Couldn't load signal library, won't respond to SIGTERM"); |
774 log("warn", "Couldn't load signal library, won't respond to SIGTERM"); |