# OfflineIMAP initialization code
-# Copyright (C) 2002, 2003 John Goerzen
+# Copyright (C) 2002-2007 John Goerzen
# <jgoerzen@complete.org>
#
# This program is free software; you can redistribute it and/or modify
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-from offlineimap import imaplib, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
+from offlineimap import imaplib2, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
from offlineimap.localeval import LocalEval
from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
from offlineimap.ui import UIBase
import re, os, os.path, offlineimap, sys
from offlineimap.CustomConfig import CustomConfigParser
from threading import *
-import threading
+import threading, socket
from getopt import getopt
+import signal
try:
import fcntl
assert versionno == version.versionstr, "Revision of main program (%s) does not match that of library (%s). Please double-check your PYTHONPATH and installation locations." % (versionno, version.versionstr)
options = {}
if '--help' in sys.argv[1:]:
- sys.stdout.write(version.cmdhelp + "\n")
+ sys.stdout.write(version.getcmdhelp() + "\n")
sys.exit(0)
- for optlist in getopt(sys.argv[1:], 'P:1oa:c:d:l:u:h')[0]:
+ for optlist in getopt(sys.argv[1:], 'P:1oqa:c:d:l:u:hk:f:')[0]:
options[optlist[0]] = optlist[1]
if options.has_key('-h'):
- sys.stdout.write(version.cmdhelp)
+ sys.stdout.write(version.getcmdhelp())
sys.stdout.write("\n")
sys.exit(0)
configfilename = os.path.expanduser("~/.offlineimaprc")
config.read(configfilename)
+ # override config values with option '-k'
+ for option in options.keys():
+ if option == '-k':
+ (key, value) = options['-k'].split('=', 1)
+ if ':' in key:
+ (secname, key) = key.split(':', 1)
+ section = secname.replace("_", " ")
+ else:
+ section = "general"
+ config.set(section, key, value)
+
ui = offlineimap.ui.detector.findUI(config, options.get('-u'))
UIBase.setglobalui(ui)
for debugtype in options['-d'].split(','):
ui.add_debug(debugtype.strip())
if debugtype == 'imap':
- imaplib.Debug = 5
+ imaplib2.Debug = 5
if debugtype == 'thread':
threading._VERBOSE = 1
for section in accounts.getaccountlist(config):
config.remove_option('Account ' + section, "autorefresh")
+ if options.has_key('-q'):
+ for section in accounts.getaccountlist(config):
+ config.set('Account ' + section, "quick", '-1')
+
+ if options.has_key('-f'):
+ foldernames = options['-f'].replace(" ", "").split(",")
+ folderfilter = "lambda f: f in %s" % foldernames
+ folderincludes = "[]"
+ for accountname in accounts.getaccountlist(config):
+ account_section = 'Account ' + accountname
+ remote_repo_section = 'Repository ' + \
+ config.get(account_section, 'remoterepository')
+ local_repo_section = 'Repository ' + \
+ config.get(account_section, 'localrepository')
+ for section in [remote_repo_section, local_repo_section]:
+ config.set(section, "folderfilter", folderfilter)
+ config.set(section, "folderincludes", folderincludes)
+
lock(config, ui)
+ def sigterm_handler(signum, frame):
+ # die immediately
+ ui.terminate(errormsg="terminating...")
+ signal.signal(signal.SIGTERM,sigterm_handler)
+
+ try:
+ pidfd = open(config.getmetadatadir() + "/pid", "w")
+ pidfd.write(str(os.getpid()) + "\n")
+ pidfd.close()
+ except:
+ pass
+
try:
if options.has_key('-l'):
sys.stderr = ui.logfile
+ socktimeout = config.getdefaultint("general", "socktimeout", 0)
+ if socktimeout > 0:
+ socket.setdefaulttimeout(socktimeout)
+
activeaccounts = config.get("general", "accounts")
if options.has_key('-a'):
activeaccounts = options['-a']
activeaccounts = activeaccounts.split(",")
allaccounts = accounts.AccountHashGenerator(config)
- syncaccounts = {}
+ syncaccounts = []
for account in activeaccounts:
if account not in allaccounts:
if len(allaccounts) == 0:
for name in allaccounts.keys():
errormsg += '\n%s'%name
ui.terminate(1, errortitle = 'Unknown Account "%s"'%account, errormsg = errormsg)
- syncaccounts[account] = allaccounts[account]
+ if account not in syncaccounts:
+ syncaccounts.append(account)
server = None
remoterepos = None
else:
threadutil.initInstanceLimit(instancename,
config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
+ siglisteners = []
+ def sig_handler(signum, frame):
+ if signum == signal.SIGUSR1:
+ # tell each account to do a full sync asap
+ signum = (1,)
+ elif signum == signal.SIGHUP:
+ # tell each account to die asap
+ signum = (2,)
+ elif signum == signal.SIGUSR2:
+ # tell each account to do a full sync asap, then die
+ signum = (1, 2)
+ # one listener per account thread (up to maxsyncaccounts)
+ for listener in siglisteners:
+ for sig in signum:
+ listener.put_nowait(sig)
+ signal.signal(signal.SIGHUP,sig_handler)
+ signal.signal(signal.SIGUSR1,sig_handler)
+ signal.signal(signal.SIGUSR2,sig_handler)
threadutil.initexitnotify()
t = ExitNotifyThread(target=syncmaster.syncitall,
name='Sync Runner',
kwargs = {'accounts': syncaccounts,
- 'config': config})
+ 'config': config,
+ 'siglisteners': siglisteners})
t.setDaemon(1)
t.start()
except: