# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import imaplib
-from offlineimap import 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
from threading import *
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
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: