Files
mailnag/mailnag
2019-10-25 19:52:24 +02:00

143 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Copyright 2011 - 2016 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
# 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.
#
import gi
gi.require_version('GLib', '2.0')
from gi.repository import GObject, GLib
from dbus.mainloop.glib import DBusGMainLoop
import threading
import argparse
import logging
import os
import signal
from Mailnag.common.utils import fix_cwd
fix_cwd()
from Mailnag.common.config import cfg_exists
from Mailnag.common.dist_cfg import APP_VERSION
from Mailnag.common.utils import set_procname, init_logging, shutdown_existing_instance
from Mailnag.common.subproc import terminate_subprocesses
from Mailnag.common.exceptions import InvalidOperationException
from Mailnag.daemon.mailnagdaemon import MailnagDaemon
PROGNAME = 'mailnag'
LOG_LEVEL = logging.DEBUG
def cleanup(daemon):
event = threading.Event()
def thread():
if daemon != None:
daemon.dispose()
terminate_subprocesses(timeout = 3.0)
event.set()
threading.Thread(target = thread).start()
event.wait(10.0)
if not event.is_set():
logging.warning('Cleanup takes too long. Enforcing termination.')
os._exit(os.EX_SOFTWARE)
if threading.active_count() > 1:
logging.warning('There are still active threads. Enforcing termination.')
os._exit(os.EX_SOFTWARE)
def get_args():
parser = argparse.ArgumentParser(prog=PROGNAME)
parser.add_argument('-q', '--quiet', action = 'store_true',
help = "don't print log messages to stdout")
parser.add_argument('-v', '--version', action = 'version',
version = '%s %s' % (PROGNAME, APP_VERSION))
return parser.parse_args()
def sigterm_handler(mainloop):
if mainloop != None:
mainloop.quit()
def main():
mainloop = GLib.MainLoop()
daemon = None
set_procname(PROGNAME)
DBusGMainLoop(set_as_default = True)
GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM,
sigterm_handler, mainloop)
# Get commandline arguments
args = get_args()
# Shut down an (possibly) already running Mailnag daemon
# (must be called before instantiation of the DBUSService).
shutdown_existing_instance()
# Note: don't start logging before an existing Mailnag
# instance has been shut down completely (will corrupt logfile).
init_logging(enable_stdout = (not args.quiet), \
enable_syslog = True, log_level = LOG_LEVEL)
try:
if not cfg_exists():
logging.critical(
"Cannot find configuration file. " + \
"Please run mailnag-config first.")
exit(1)
def fatal_error_hdlr(ex):
# Note: don't raise an exception
# (e.g InvalidOperationException)
# in the error handler.
mainloop.quit()
def shutdown_request_hdlr():
if not mainloop.is_running():
raise InvalidOperationException(
"Mainloop is not running")
mainloop.quit()
daemon = MailnagDaemon(
fatal_error_hdlr,
shutdown_request_hdlr)
daemon.init()
# start mainloop for DBus communication
mainloop.run()
except KeyboardInterrupt:
pass # ctrl+c pressed
finally:
logging.info('Shutting down...')
cleanup(daemon)
if __name__ == '__main__': main()