2008-08-15 19:31:51 +02:00
|
|
|
# -*- coding:utf-8 -*-
|
2008-08-15 05:20:23 +02:00
|
|
|
## src/gajim.py
|
2003-11-30 23:40:24 +01:00
|
|
|
##
|
2014-01-02 09:33:54 +01:00
|
|
|
## Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
|
2008-08-15 05:20:23 +02:00
|
|
|
## Copyright (C) 2004-2005 Vincent Hanquez <tab AT snarc.org>
|
|
|
|
## Copyright (C) 2005 Alex Podaras <bigpod AT gmail.com>
|
|
|
|
## Norman Rasmussen <norman AT rasmussen.co.za>
|
2008-08-15 19:31:51 +02:00
|
|
|
## Stéphan Kochen <stephan AT kochen.nl>
|
2008-08-15 05:20:23 +02:00
|
|
|
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
|
|
|
|
## Alex Mauer <hawke AT hawkesnest.net>
|
|
|
|
## Copyright (C) 2005-2007 Travis Shirk <travis AT pobox.com>
|
|
|
|
## Nikos Kouremenos <kourem AT gmail.com>
|
2008-08-15 19:31:51 +02:00
|
|
|
## Copyright (C) 2006 Junglecow J <junglecow AT gmail.com>
|
2008-08-15 05:20:23 +02:00
|
|
|
## Stefan Bethge <stefan AT lanpartei.de>
|
|
|
|
## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
|
|
|
|
## Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
|
|
|
|
## James Newton <redshodan AT gmail.com>
|
|
|
|
## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
|
|
|
|
## Julien Pivotto <roidelapluie AT gmail.com>
|
|
|
|
## Stephan Erb <steve-e AT h3c.de>
|
|
|
|
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
2003-11-30 23:40:24 +01:00
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## This file is part of Gajim.
|
|
|
|
##
|
|
|
|
## Gajim is free software; you can redistribute it and/or modify
|
2003-11-30 23:40:24 +01:00
|
|
|
## it under the terms of the GNU General Public License as published
|
2007-12-12 09:44:46 +01:00
|
|
|
## by the Free Software Foundation; version 3 only.
|
2003-11-30 23:40:24 +01:00
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## Gajim is distributed in the hope that it will be useful,
|
2003-11-30 23:40:24 +01:00
|
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2008-08-15 05:20:23 +02:00
|
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2003-11-30 23:40:24 +01:00
|
|
|
## GNU General Public License for more details.
|
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## You should have received a copy of the GNU General Public License
|
2008-08-15 05:20:23 +02:00
|
|
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
2007-12-12 09:44:46 +01:00
|
|
|
##
|
2005-11-13 15:55:52 +01:00
|
|
|
|
2011-09-12 23:52:22 +02:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import warnings
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
log_path = os.path.join(os.environ['APPDATA'], 'Gajim')
|
|
|
|
if not os.path.exists(log_path):
|
2013-01-01 19:36:56 +01:00
|
|
|
os.mkdir(log_path, 0o700)
|
2011-09-12 23:52:22 +02:00
|
|
|
log_file = os.path.join(log_path, 'gajim.log')
|
|
|
|
fout = open(log_file, 'a')
|
|
|
|
sys.stdout = fout
|
|
|
|
sys.stderr = fout
|
|
|
|
|
|
|
|
warnings.filterwarnings(action='ignore')
|
|
|
|
|
|
|
|
if os.path.isdir('gtk'):
|
|
|
|
# Used to create windows installer with GTK included
|
|
|
|
paths = os.environ['PATH']
|
|
|
|
list_ = paths.split(';')
|
|
|
|
new_list = []
|
|
|
|
for p in list_:
|
|
|
|
if p.find('gtk') < 0 and p.find('GTK') < 0:
|
|
|
|
new_list.append(p)
|
|
|
|
new_list.insert(0, os.path.join(os.getcwd(), 'gtk', 'lib'))
|
|
|
|
new_list.insert(0, os.path.join(os.getcwd(), 'gtk', 'bin'))
|
|
|
|
os.environ['PATH'] = ';'.join(new_list)
|
|
|
|
|
2014-03-09 10:25:26 +01:00
|
|
|
# Needs to be imported very early to not crash Gajim on exit.
|
|
|
|
try:
|
|
|
|
__import__('libxml2mod')
|
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
|
2014-04-09 18:02:30 +02:00
|
|
|
HAS_NBXMPP=True
|
2015-07-20 19:47:30 +02:00
|
|
|
MIN_NBXMPP_VER = "0.5.3"
|
2012-12-09 21:37:51 +01:00
|
|
|
try:
|
|
|
|
import nbxmpp
|
|
|
|
except ImportError:
|
2014-04-09 18:02:30 +02:00
|
|
|
HAS_NBXMPP=False
|
|
|
|
|
|
|
|
if not HAS_NBXMPP:
|
2013-01-01 19:36:56 +01:00
|
|
|
print('Gajim needs python-nbxmpp to run. Quiting...')
|
2012-12-09 21:37:51 +01:00
|
|
|
sys.exit()
|
|
|
|
|
2013-12-23 16:56:58 +01:00
|
|
|
try:
|
|
|
|
from distutils.version import LooseVersion as V
|
2014-04-09 18:02:30 +02:00
|
|
|
if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER):
|
|
|
|
HAS_NBXMPP=False
|
2013-12-23 16:56:58 +01:00
|
|
|
except:
|
2014-04-09 18:02:30 +02:00
|
|
|
HAS_NBXMPP=False
|
|
|
|
|
|
|
|
if not HAS_NBXMPP:
|
2014-11-14 22:31:18 +01:00
|
|
|
print('Gajim needs python-nbxmpp >= %s to run. Quiting...' % MIN_NBXMPP_VER)
|
2013-12-23 16:56:58 +01:00
|
|
|
sys.exit()
|
|
|
|
|
2012-12-23 16:23:43 +01:00
|
|
|
#from common import demandimport
|
|
|
|
#demandimport.enable()
|
|
|
|
#demandimport.ignore += ['GObject._gobject', 'libasyncns', 'i18n',
|
|
|
|
# 'logging.NullHandler', 'dbus.service', 'OpenSSL.SSL', 'OpenSSL.crypto',
|
|
|
|
# 'common.sleepy', 'DLFCN', 'dl', 'xml.sax', 'xml.sax.handler', 'ic',
|
2013-08-25 18:57:27 +02:00
|
|
|
# 'Crypto.PublicKey', 'IPython', 'contextlib', 'imp', 'monotonic',
|
2015-11-04 21:54:24 +01:00
|
|
|
# 'gtkexcepthook', 'libxml2', 'libxml2mod']
|
2010-12-17 10:17:57 +01:00
|
|
|
|
2010-10-26 17:28:08 +02:00
|
|
|
if os.name == 'nt':
|
|
|
|
import locale
|
|
|
|
import gettext
|
|
|
|
APP = 'gajim'
|
|
|
|
DIR = '../po'
|
|
|
|
lang, enc = locale.getdefaultlocale()
|
|
|
|
os.environ['LANG'] = lang
|
|
|
|
gettext.bindtextdomain(APP, DIR)
|
|
|
|
gettext.textdomain(APP)
|
2013-01-01 21:06:16 +01:00
|
|
|
gettext.install(APP, DIR)
|
2010-10-26 17:28:08 +02:00
|
|
|
|
|
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
|
|
import ctypes
|
2010-10-27 09:41:04 +02:00
|
|
|
import ctypes.util
|
|
|
|
libintl_path = ctypes.util.find_library('intl')
|
|
|
|
if libintl_path == None:
|
2010-10-28 13:18:37 +02:00
|
|
|
local_intl = os.path.join('gtk', 'bin', 'intl.dll')
|
2010-10-27 09:41:04 +02:00
|
|
|
if os.path.exists(local_intl):
|
|
|
|
libintl_path = local_intl
|
|
|
|
if libintl_path == None:
|
|
|
|
raise ImportError('intl.dll library not found')
|
|
|
|
libintl = ctypes.cdll.LoadLibrary(libintl_path)
|
2010-10-26 17:28:08 +02:00
|
|
|
libintl.bindtextdomain(APP, DIR)
|
2010-12-06 23:33:42 +01:00
|
|
|
libintl.bind_textdomain_codeset(APP, 'UTF-8')
|
2010-10-26 17:28:08 +02:00
|
|
|
|
2008-11-19 22:47:28 +01:00
|
|
|
if os.name == 'nt':
|
2010-02-08 15:08:40 +01:00
|
|
|
# needed for docutils
|
|
|
|
sys.path.append('.')
|
2008-11-19 22:47:28 +01:00
|
|
|
|
2009-03-11 10:16:07 +01:00
|
|
|
from common import logging_helpers
|
2014-03-08 10:07:40 +01:00
|
|
|
logging_helpers.init(sys.stderr.isatty())
|
2009-03-11 10:16:07 +01:00
|
|
|
|
2006-12-23 22:18:07 +01:00
|
|
|
import logging
|
2009-03-11 10:16:07 +01:00
|
|
|
# gajim.gui or gajim.gtk more appropriate ?
|
2006-12-23 22:18:07 +01:00
|
|
|
log = logging.getLogger('gajim.gajim')
|
|
|
|
|
2015-07-30 15:15:38 +02:00
|
|
|
import gi
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
|
|
gi.require_version('Gdk', '3.0')
|
|
|
|
gi.require_version('GObject', '2.0')
|
|
|
|
gi.require_version('Pango', '1.0')
|
2012-12-23 16:23:43 +01:00
|
|
|
|
2006-12-23 22:18:07 +01:00
|
|
|
import getopt
|
2009-10-18 23:56:04 +02:00
|
|
|
from common import i18n
|
2006-06-15 08:49:04 +02:00
|
|
|
|
2006-12-23 22:18:07 +01:00
|
|
|
def parseOpts():
|
2010-02-10 14:00:28 +01:00
|
|
|
profile_ = ''
|
|
|
|
config_path_ = None
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
try:
|
|
|
|
shortargs = 'hqvl:p:c:'
|
2011-05-11 20:02:16 +02:00
|
|
|
# add gtk/gnome session option as gtk_get_option_group is not wrapped
|
2013-08-25 16:14:38 +02:00
|
|
|
longargs = 'help quiet verbose loglevel= profile= config-path='
|
2011-05-11 20:02:16 +02:00
|
|
|
longargs += ' class= name= screen= gtk-module= sync g-fatal-warnings'
|
|
|
|
longargs += ' sm-client-id= sm-client-state-file= sm-disable'
|
2010-02-08 15:08:40 +01:00
|
|
|
opts = getopt.getopt(sys.argv[1:], shortargs, longargs.split())[0]
|
2013-01-01 19:36:56 +01:00
|
|
|
except getopt.error as msg1:
|
2013-01-05 00:03:36 +01:00
|
|
|
print(str(msg1))
|
2013-01-01 19:36:56 +01:00
|
|
|
print('for help use --help')
|
2010-02-08 15:08:40 +01:00
|
|
|
sys.exit(2)
|
|
|
|
for o, a in opts:
|
|
|
|
if o in ('-h', '--help'):
|
2014-03-02 11:26:52 +01:00
|
|
|
out = _('Usage:') + \
|
2013-08-25 22:59:46 +02:00
|
|
|
'\n gajim [options] filename\n\n' + \
|
|
|
|
_('Options:') + \
|
2013-08-25 22:40:05 +02:00
|
|
|
'\n -h, --help ' + \
|
|
|
|
_('Show this help message and exit') + \
|
2013-08-25 22:59:46 +02:00
|
|
|
'\n -q, --quiet ' + \
|
|
|
|
_('Show only critical errors') + \
|
2013-08-25 22:40:05 +02:00
|
|
|
'\n -v, --verbose ' + \
|
|
|
|
_('Print xml stanzas and other debug information') + \
|
|
|
|
'\n -p, --profile ' + \
|
2013-08-26 07:32:16 +02:00
|
|
|
_('Use defined profile in configuration directory') + \
|
2013-08-25 22:40:05 +02:00
|
|
|
'\n -c, --config-path ' + \
|
|
|
|
_('Set configuration directory') + \
|
|
|
|
'\n -l, --loglevel ' + \
|
2014-03-02 11:26:52 +01:00
|
|
|
_('Configure logging system') + '\n'
|
2016-01-03 16:14:44 +01:00
|
|
|
print(out)
|
2010-02-08 15:08:40 +01:00
|
|
|
sys.exit()
|
|
|
|
elif o in ('-q', '--quiet'):
|
|
|
|
logging_helpers.set_quiet()
|
|
|
|
elif o in ('-v', '--verbose'):
|
|
|
|
logging_helpers.set_verbose()
|
|
|
|
elif o in ('-p', '--profile'): # gajim --profile name
|
2010-02-10 14:00:28 +01:00
|
|
|
profile_ = a
|
2010-02-08 15:08:40 +01:00
|
|
|
elif o in ('-l', '--loglevel'):
|
|
|
|
logging_helpers.set_loglevels(a)
|
|
|
|
elif o in ('-c', '--config-path'):
|
2010-02-10 14:00:28 +01:00
|
|
|
config_path_ = a
|
|
|
|
return profile_, config_path_
|
2006-12-23 22:18:07 +01:00
|
|
|
|
2011-10-23 18:55:14 +02:00
|
|
|
import locale
|
2009-03-11 10:16:07 +01:00
|
|
|
profile, config_path = parseOpts()
|
|
|
|
del parseOpts
|
2006-12-23 22:18:07 +01:00
|
|
|
|
2007-08-09 17:39:18 +02:00
|
|
|
import common.configpaths
|
|
|
|
common.configpaths.gajimpaths.init(config_path)
|
|
|
|
del config_path
|
|
|
|
common.configpaths.gajimpaths.init_profile(profile)
|
|
|
|
del profile
|
|
|
|
|
2009-03-01 14:12:38 +01:00
|
|
|
if os.name == 'nt':
|
2011-10-23 18:55:14 +02:00
|
|
|
plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[
|
|
|
|
'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding())
|
2011-09-02 19:41:09 +02:00
|
|
|
libintl.bindtextdomain('gajim_plugins', plugins_locale_dir)
|
|
|
|
libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8')
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
class MyStderr(object):
|
|
|
|
_file = None
|
|
|
|
_error = None
|
|
|
|
def write(self, text):
|
2010-02-08 23:22:06 +01:00
|
|
|
fname = os.path.join(common.configpaths.gajimpaths.cache_root,
|
|
|
|
os.path.split(sys.executable)[1]+'.log')
|
2010-02-08 15:08:40 +01:00
|
|
|
if self._file is None and self._error is None:
|
|
|
|
try:
|
|
|
|
self._file = open(fname, 'a')
|
2013-01-01 19:36:56 +01:00
|
|
|
except Exception as details:
|
2010-02-08 15:08:40 +01:00
|
|
|
self._error = details
|
|
|
|
if self._file is not None:
|
|
|
|
self._file.write(text)
|
|
|
|
self._file.flush()
|
|
|
|
def flush(self):
|
|
|
|
if self._file is not None:
|
|
|
|
self._file.flush()
|
|
|
|
|
|
|
|
sys.stderr = MyStderr()
|
2009-03-01 14:12:38 +01:00
|
|
|
|
2007-12-12 09:44:46 +01:00
|
|
|
# PyGTK2.10+ only throws a warning
|
2015-07-20 20:08:55 +02:00
|
|
|
warnings.filterwarnings('error', module='Gtk')
|
2007-12-12 09:44:46 +01:00
|
|
|
try:
|
2012-12-23 16:23:43 +01:00
|
|
|
from gi.repository import GObject
|
|
|
|
GObject.set_prgname('gajim')
|
|
|
|
from gi.repository import Gtk
|
|
|
|
from gi.repository import Gdk
|
2013-11-30 10:00:10 +01:00
|
|
|
from gi.repository import GLib
|
2013-01-01 19:36:56 +01:00
|
|
|
except Warning as msg2:
|
2010-02-10 14:00:28 +01:00
|
|
|
if str(msg2) == 'could not open display':
|
2013-01-01 19:36:56 +01:00
|
|
|
print(_('Gajim needs X server to run. Quiting...'), file=sys.stderr)
|
2010-02-08 15:08:40 +01:00
|
|
|
else:
|
2013-01-01 19:36:56 +01:00
|
|
|
print(_('importing PyGTK failed: %s') % str(msg2), file=sys.stderr)
|
2010-02-08 15:08:40 +01:00
|
|
|
sys.exit()
|
2007-12-12 09:44:46 +01:00
|
|
|
warnings.resetwarnings()
|
|
|
|
|
2010-03-31 08:19:21 +02:00
|
|
|
|
2008-04-04 23:31:27 +02:00
|
|
|
if os.name == 'nt':
|
2010-02-08 15:08:40 +01:00
|
|
|
warnings.filterwarnings(action='ignore')
|
2008-04-04 23:31:27 +02:00
|
|
|
|
2013-08-02 11:44:15 +02:00
|
|
|
if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL:
|
|
|
|
i18n.direction_mark = '\u200F'
|
2005-12-01 18:17:20 +01:00
|
|
|
pritext = ''
|
2005-09-11 16:20:20 +02:00
|
|
|
|
2008-03-17 08:22:43 +01:00
|
|
|
from common import exceptions
|
2005-09-22 18:30:46 +02:00
|
|
|
try:
|
2010-02-08 15:08:40 +01:00
|
|
|
from common import gajim
|
2008-03-17 08:22:43 +01:00
|
|
|
except exceptions.DatabaseMalformed:
|
2010-02-08 15:08:40 +01:00
|
|
|
pritext = _('Database Error')
|
2010-02-08 23:22:06 +01:00
|
|
|
sectext = _('The database file (%s) cannot be read. Try to repair it (see '
|
|
|
|
'http://trac.gajim.org/wiki/DatabaseBackup) or remove it (all history '
|
|
|
|
'will be lost).') % common.logger.LOG_DB_PATH
|
2008-03-17 08:22:43 +01:00
|
|
|
else:
|
2013-01-02 13:54:02 +01:00
|
|
|
from common import logger
|
|
|
|
gajim.logger = logger.Logger()
|
|
|
|
from common import caps_cache
|
|
|
|
caps_cache.initialize(gajim.logger)
|
2010-02-08 15:08:40 +01:00
|
|
|
from common import dbus_support
|
|
|
|
if dbus_support.supported:
|
|
|
|
from music_track_listener import MusicTrackListener
|
|
|
|
|
|
|
|
from ctypes import CDLL
|
|
|
|
from ctypes.util import find_library
|
|
|
|
import platform
|
|
|
|
|
|
|
|
sysname = platform.system()
|
|
|
|
if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'):
|
|
|
|
libc = CDLL(find_library('c'))
|
|
|
|
|
2010-02-08 23:22:06 +01:00
|
|
|
# The constant defined in <linux/prctl.h> which is used to set the name
|
|
|
|
# of the process.
|
2010-02-08 15:08:40 +01:00
|
|
|
PR_SET_NAME = 15
|
|
|
|
|
|
|
|
if sysname == 'Linux':
|
|
|
|
libc.prctl(PR_SET_NAME, 'gajim')
|
|
|
|
elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'):
|
|
|
|
libc.setproctitle('gajim')
|
|
|
|
|
2012-12-23 16:23:43 +01:00
|
|
|
# if Gtk.pygtk_version < (2, 22, 0):
|
|
|
|
# pritext = _('Gajim needs PyGTK 2.22 or above')
|
|
|
|
# sectext = _('Gajim needs PyGTK 2.22 or above to run. Quiting...')
|
|
|
|
# elif Gtk.gtk_version < (2, 22, 0):
|
|
|
|
# if (Gtk.get_major_version(), Gtk.get_minor_version(),
|
|
|
|
# Gtk.get_micro_version()) < (2, 22, 0):
|
|
|
|
# pritext = _('Gajim needs GTK 2.22 or above')
|
|
|
|
# sectext = _('Gajim needs GTK 2.22 or above to run. Quiting...')
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-02-08 23:22:06 +01:00
|
|
|
from common import check_paths
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
try:
|
|
|
|
import winsound # windows-only built-in module for playing wav
|
|
|
|
import win32api # do NOT remove. we req this module
|
|
|
|
except Exception:
|
|
|
|
pritext = _('Gajim needs pywin32 to run')
|
2010-02-08 23:22:06 +01:00
|
|
|
sectext = _('Please make sure that Pywin32 is installed on your '
|
|
|
|
'system. You can get it at %s') % \
|
|
|
|
'http://sourceforge.net/project/showfiles.php?group_id=78018'
|
2006-09-13 18:47:58 +02:00
|
|
|
|
2005-12-01 18:17:20 +01:00
|
|
|
if pritext:
|
2012-12-23 16:23:43 +01:00
|
|
|
dlg = Gtk.MessageDialog(None,
|
|
|
|
Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
|
|
|
|
Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, message_format = pritext)
|
2005-09-22 18:30:46 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
dlg.format_secondary_text(sectext)
|
|
|
|
dlg.run()
|
|
|
|
dlg.destroy()
|
|
|
|
sys.exit()
|
2005-09-22 18:30:46 +02:00
|
|
|
|
2007-02-04 15:09:38 +01:00
|
|
|
del pritext
|
|
|
|
|
2009-10-18 23:56:04 +02:00
|
|
|
import gtkexcepthook
|
|
|
|
|
2009-11-03 22:14:19 +01:00
|
|
|
import signal
|
2005-07-25 16:38:21 +02:00
|
|
|
import gtkgui_helpers
|
2005-04-14 09:05:10 +02:00
|
|
|
|
2006-11-18 21:52:28 +01:00
|
|
|
gajimpaths = common.configpaths.gajimpaths
|
|
|
|
|
|
|
|
pid_filename = gajimpaths['PID_FILE']
|
2009-10-18 23:56:04 +02:00
|
|
|
config_filename = gajimpaths['CONFIG_FILE']
|
2006-11-18 21:52:28 +01:00
|
|
|
|
2013-11-10 08:39:50 +01:00
|
|
|
# Seed the OpenSSL pseudo random number generator from file and initialize
|
|
|
|
RNG_SEED = gajimpaths['RNG_SEED']
|
|
|
|
PYOPENSSL_PRNG_PRESENT = False
|
|
|
|
try:
|
|
|
|
import OpenSSL.rand
|
|
|
|
from common import crypto
|
|
|
|
PYOPENSSL_PRNG_PRESENT = True
|
|
|
|
# Seed from file
|
2014-02-18 10:09:03 +01:00
|
|
|
try:
|
|
|
|
OpenSSL.rand.load_file(RNG_SEED)
|
|
|
|
except TypeError:
|
|
|
|
OpenSSL.rand.load_file(RNG_SEED.encode('utf-8'))
|
2013-11-10 08:39:50 +01:00
|
|
|
crypto.add_entropy_sources_OpenSSL()
|
2015-01-05 21:45:42 +01:00
|
|
|
try:
|
|
|
|
OpenSSL.rand.write_file(RNG_SEED)
|
|
|
|
except TypeError:
|
|
|
|
OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
|
2013-11-10 08:39:50 +01:00
|
|
|
except ImportError:
|
|
|
|
log.info("PyOpenSSL PRNG not available")
|
|
|
|
|
2006-11-22 21:56:25 +01:00
|
|
|
import traceback
|
|
|
|
import errno
|
2006-06-14 10:45:30 +02:00
|
|
|
import dialogs
|
2009-11-03 22:14:19 +01:00
|
|
|
|
2006-11-22 17:15:16 +01:00
|
|
|
def pid_alive():
|
2010-02-08 15:08:40 +01:00
|
|
|
try:
|
|
|
|
pf = open(pid_filename)
|
|
|
|
except IOError:
|
|
|
|
# probably file not found
|
|
|
|
return False
|
|
|
|
|
|
|
|
try:
|
|
|
|
pid = int(pf.read().strip())
|
|
|
|
pf.close()
|
|
|
|
except Exception:
|
|
|
|
traceback.print_exc()
|
|
|
|
# PID file exists, but something happened trying to read PID
|
|
|
|
# Could be 0.10 style empty PID file, so assume Gajim is running
|
|
|
|
return True
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
try:
|
2010-02-08 23:22:06 +01:00
|
|
|
from ctypes import (windll, c_ulong, c_int, Structure, c_char)
|
2010-03-19 11:33:50 +01:00
|
|
|
from ctypes import (POINTER, pointer, sizeof)
|
2010-02-08 15:08:40 +01:00
|
|
|
except Exception:
|
|
|
|
return True
|
|
|
|
|
|
|
|
class PROCESSENTRY32(Structure):
|
|
|
|
_fields_ = [
|
|
|
|
('dwSize', c_ulong, ),
|
|
|
|
('cntUsage', c_ulong, ),
|
|
|
|
('th32ProcessID', c_ulong, ),
|
|
|
|
('th32DefaultHeapID', c_ulong, ),
|
|
|
|
('th32ModuleID', c_ulong, ),
|
|
|
|
('cntThreads', c_ulong, ),
|
|
|
|
('th32ParentProcessID', c_ulong, ),
|
|
|
|
('pcPriClassBase', c_ulong, ),
|
|
|
|
('dwFlags', c_ulong, ),
|
|
|
|
('szExeFile', c_char*512, ),
|
|
|
|
]
|
|
|
|
|
2010-03-19 11:33:50 +01:00
|
|
|
kernel = windll.kernel32
|
|
|
|
kernel.CreateToolhelp32Snapshot.argtypes = c_ulong, c_ulong,
|
|
|
|
kernel.CreateToolhelp32Snapshot.restype = c_int
|
|
|
|
kernel.Process32First.argtypes = c_int, POINTER(PROCESSENTRY32),
|
|
|
|
kernel.Process32First.restype = c_int
|
|
|
|
kernel.Process32Next.argtypes = c_int, POINTER(PROCESSENTRY32),
|
|
|
|
kernel.Process32Next.restype = c_int
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-02-10 14:00:28 +01:00
|
|
|
def get_p(pid_):
|
2010-03-19 11:33:50 +01:00
|
|
|
TH32CS_SNAPPROCESS = 2
|
|
|
|
CreateToolhelp32Snapshot = kernel.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
|
|
|
|
assert CreateToolhelp32Snapshot > 0, 'CreateToolhelp32Snapshot failed'
|
|
|
|
pe32 = PROCESSENTRY32()
|
|
|
|
pe32.dwSize = sizeof( PROCESSENTRY32 )
|
|
|
|
f3 = kernel.Process32First(CreateToolhelp32Snapshot, pointer(pe32))
|
2010-02-10 14:00:28 +01:00
|
|
|
while f3:
|
2010-03-19 11:33:50 +01:00
|
|
|
if pe32.th32ProcessID == pid_:
|
|
|
|
return pe32.szExeFile
|
|
|
|
f3 = kernel.Process32Next(CreateToolhelp32Snapshot, pointer(pe32))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if get_p(pid) in ('python.exe', 'gajim.exe'):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
try:
|
|
|
|
if not os.path.exists('/proc'):
|
|
|
|
return True # no /proc, assume Gajim is running
|
|
|
|
|
|
|
|
try:
|
2010-02-10 14:00:28 +01:00
|
|
|
f1 = open('/proc/%d/cmdline'% pid)
|
2013-01-01 19:36:56 +01:00
|
|
|
except IOError as e1:
|
2010-02-10 14:00:28 +01:00
|
|
|
if e1.errno == errno.ENOENT:
|
2010-02-08 15:08:40 +01:00
|
|
|
return False # file/pid does not exist
|
|
|
|
raise
|
|
|
|
|
2010-02-10 14:00:28 +01:00
|
|
|
n = f1.read().lower()
|
|
|
|
f1.close()
|
2010-02-08 15:08:40 +01:00
|
|
|
if n.find('gajim') < 0:
|
|
|
|
return False
|
|
|
|
return True # Running Gajim found at pid
|
|
|
|
except Exception:
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
# If we are here, pidfile exists, but some unexpected error occured.
|
|
|
|
# Assume Gajim is running.
|
|
|
|
return True
|
2006-11-22 17:15:16 +01:00
|
|
|
|
2012-12-09 11:51:36 +01:00
|
|
|
def show_remote_gajim_roster():
|
|
|
|
try:
|
|
|
|
import dbus
|
|
|
|
|
|
|
|
OBJ_PATH = '/org/gajim/dbus/RemoteObject'
|
|
|
|
INTERFACE = 'org.gajim.dbus.RemoteInterface'
|
|
|
|
SERVICE = 'org.gajim.dbus'
|
|
|
|
|
|
|
|
# Attempt to call show_roster
|
|
|
|
dbus.Interface(dbus.SessionBus().get_object(SERVICE, OBJ_PATH), INTERFACE).__getattr__("show_roster")()
|
|
|
|
|
|
|
|
return True
|
|
|
|
except Exception:
|
|
|
|
return False
|
|
|
|
|
2006-11-22 17:15:16 +01:00
|
|
|
if pid_alive():
|
2012-12-09 11:51:36 +01:00
|
|
|
if (show_remote_gajim_roster()):
|
|
|
|
print("Gajim is already running, bringing the roster to front...")
|
|
|
|
sys.exit(0)
|
2013-01-14 20:18:55 +01:00
|
|
|
pixs = []
|
|
|
|
for size in (16, 32, 48, 64, 128):
|
|
|
|
pix = gtkgui_helpers.get_icon_pixmap('gajim', size)
|
|
|
|
if pix:
|
|
|
|
pixs.append(pix)
|
|
|
|
if pixs:
|
|
|
|
# set the icon to all windows
|
2015-11-23 20:45:21 +01:00
|
|
|
Gtk.Window.set_default_icon_list(pixs)
|
2010-02-08 15:08:40 +01:00
|
|
|
pritext = _('Gajim is already running')
|
|
|
|
sectext = _('Another instance of Gajim seems to be running\nRun anyway?')
|
|
|
|
dialog = dialogs.YesNoDialog(pritext, sectext)
|
|
|
|
dialog.popup()
|
2012-12-23 16:23:43 +01:00
|
|
|
if dialog.run() != Gtk.ResponseType.YES:
|
2010-02-08 15:08:40 +01:00
|
|
|
sys.exit(3)
|
|
|
|
dialog.destroy()
|
|
|
|
# run anyway, delete pid and useless global vars
|
|
|
|
if os.path.exists(pid_filename):
|
|
|
|
os.remove(pid_filename)
|
|
|
|
del pix
|
|
|
|
del pritext
|
|
|
|
del sectext
|
|
|
|
dialog.destroy()
|
2006-05-26 15:32:52 +02:00
|
|
|
|
2006-06-15 11:49:44 +02:00
|
|
|
# Create .gajim dir
|
|
|
|
pid_dir = os.path.dirname(pid_filename)
|
|
|
|
if not os.path.exists(pid_dir):
|
2010-02-08 15:08:40 +01:00
|
|
|
check_paths.create_path(pid_dir)
|
2006-06-15 11:49:44 +02:00
|
|
|
# Create pid file
|
2007-08-09 17:39:18 +02:00
|
|
|
try:
|
2010-02-10 14:00:28 +01:00
|
|
|
f2 = open(pid_filename, 'w')
|
|
|
|
f2.write(str(os.getpid()))
|
|
|
|
f2.close()
|
2013-01-01 19:36:56 +01:00
|
|
|
except IOError as e2:
|
2010-02-10 14:00:28 +01:00
|
|
|
dlg = dialogs.ErrorDialog(_('Disk Write Error'), str(e2))
|
2010-02-08 15:08:40 +01:00
|
|
|
dlg.run()
|
|
|
|
dlg.destroy()
|
|
|
|
sys.exit()
|
2006-11-21 19:46:33 +01:00
|
|
|
del pid_dir
|
2006-05-26 15:32:52 +02:00
|
|
|
|
|
|
|
def on_exit():
|
2013-11-10 08:39:50 +01:00
|
|
|
# Save the entropy from OpenSSL PRNG
|
|
|
|
if PYOPENSSL_PRNG_PRESENT:
|
2014-02-18 10:09:03 +01:00
|
|
|
try:
|
|
|
|
OpenSSL.rand.write_file(RNG_SEED)
|
|
|
|
except TypeError:
|
|
|
|
OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
|
2010-02-08 15:08:40 +01:00
|
|
|
# delete pid file on normal exit
|
|
|
|
if os.path.exists(pid_filename):
|
|
|
|
os.remove(pid_filename)
|
|
|
|
# Shutdown GUI and save config
|
2010-10-26 17:28:08 +02:00
|
|
|
if hasattr(gajim.interface, 'roster') and gajim.interface.roster:
|
2010-02-08 15:08:40 +01:00
|
|
|
gajim.interface.roster.prepare_quit()
|
2006-05-26 15:32:52 +02:00
|
|
|
|
|
|
|
import atexit
|
|
|
|
atexit.register(on_exit)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2009-11-03 22:14:19 +01:00
|
|
|
from gui_interface import Interface
|
2008-11-05 21:00:57 +01:00
|
|
|
|
2005-04-12 23:09:06 +02:00
|
|
|
if __name__ == '__main__':
|
2010-02-08 15:08:40 +01:00
|
|
|
def sigint_cb(num, stack):
|
|
|
|
sys.exit(5)
|
|
|
|
# ^C exits the application normally to delete pid file
|
|
|
|
signal.signal(signal.SIGINT, sigint_cb)
|
2012-04-19 16:57:43 +02:00
|
|
|
signal.signal(signal.SIGTERM, sigint_cb)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), \
|
|
|
|
sys.getfilesystemencoding(), locale.getpreferredencoding())
|
|
|
|
|
|
|
|
check_paths.check_and_possibly_create_paths()
|
|
|
|
|
|
|
|
interface = Interface()
|
|
|
|
interface.run()
|
|
|
|
|
|
|
|
try:
|
2012-12-23 16:23:43 +01:00
|
|
|
Gtk.main()
|
2010-02-08 15:08:40 +01:00
|
|
|
except KeyboardInterrupt:
|
2013-01-01 19:36:56 +01:00
|
|
|
print('KeyboardInterrupt', file=sys.stderr)
|