]> code.delx.au - offlineimap/blob - offlineimap/init.py
Update FSF address
[offlineimap] / offlineimap / init.py
1 # OfflineIMAP initialization code
2 # Copyright (C) 2002, 2003 John Goerzen
3 # <jgoerzen@complete.org>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 from offlineimap import imaplib, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
20 from offlineimap.localeval import LocalEval
21 from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
22 from offlineimap.ui import UIBase
23 import re, os, os.path, offlineimap, sys
24 from offlineimap.CustomConfig import CustomConfigParser
25 from threading import *
26 import threading
27 from getopt import getopt
28
29 try:
30 import fcntl
31 hasfcntl = 1
32 except:
33 hasfcntl = 0
34
35 lockfd = None
36
37 def lock(config, ui):
38 global lockfd, hasfcntl
39 if not hasfcntl:
40 return
41 lockfd = open(config.getmetadatadir() + "/lock", "w")
42 try:
43 fcntl.flock(lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
44 except IOError:
45 ui.locked()
46 ui.terminate(1)
47
48 def startup(versionno):
49 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)
50 options = {}
51 if '--help' in sys.argv[1:]:
52 sys.stdout.write(version.cmdhelp + "\n")
53 sys.exit(0)
54
55 for optlist in getopt(sys.argv[1:], 'P:1oa:c:d:l:u:h')[0]:
56 options[optlist[0]] = optlist[1]
57
58 if options.has_key('-h'):
59 sys.stdout.write(version.cmdhelp)
60 sys.stdout.write("\n")
61 sys.exit(0)
62 configfilename = os.path.expanduser("~/.offlineimaprc")
63 if options.has_key('-c'):
64 configfilename = options['-c']
65 if options.has_key('-P'):
66 if not options.has_key('-1'):
67 sys.stderr.write("FATAL: profile mode REQUIRES -1\n")
68 sys.exit(100)
69 profiledir = options['-P']
70 os.mkdir(profiledir)
71 threadutil.setprofiledir(profiledir)
72 sys.stderr.write("WARNING: profile mode engaged;\nPotentially large data will be created in " + profiledir + "\n")
73
74 config = CustomConfigParser()
75 if not os.path.exists(configfilename):
76 sys.stderr.write(" *** Config file %s does not exist; aborting!\n" % configfilename)
77 sys.exit(1)
78
79 config.read(configfilename)
80
81 ui = offlineimap.ui.detector.findUI(config, options.get('-u'))
82 UIBase.setglobalui(ui)
83
84 if options.has_key('-l'):
85 ui.setlogfd(open(options['-l'], 'wt'))
86
87 ui.init_banner()
88
89 if options.has_key('-d'):
90 for debugtype in options['-d'].split(','):
91 ui.add_debug(debugtype.strip())
92 if debugtype == 'imap':
93 imaplib.Debug = 5
94 if debugtype == 'thread':
95 threading._VERBOSE = 1
96
97 if options.has_key('-o'):
98 # FIXME: maybe need a better
99 for section in accounts.getaccountlist(config):
100 config.remove_option('Account ' + section, "autorefresh")
101
102 lock(config, ui)
103
104 if options.has_key('-l'):
105 sys.stderr = ui.logfile
106
107 activeaccounts = config.get("general", "accounts")
108 if options.has_key('-a'):
109 activeaccounts = options['-a']
110 activeaccounts = activeaccounts.replace(" ", "")
111 activeaccounts = activeaccounts.split(",")
112 allaccounts = accounts.AccountHashGenerator(config)
113
114 syncaccounts = {}
115 for account in activeaccounts:
116 syncaccounts[account] = allaccounts[account]
117
118 server = None
119 remoterepos = None
120 localrepos = None
121
122 if options.has_key('-1'):
123 threadutil.initInstanceLimit("ACCOUNTLIMIT", 1)
124 else:
125 threadutil.initInstanceLimit("ACCOUNTLIMIT",
126 config.getdefaultint("general", "maxsyncaccounts", 1))
127
128 for reposname in config.getsectionlist('Repository'):
129 for instancename in ["FOLDER_" + reposname,
130 "MSGCOPY_" + reposname]:
131 if options.has_key('-1'):
132 threadutil.initInstanceLimit(instancename, 1)
133 else:
134 threadutil.initInstanceLimit(instancename,
135 config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
136
137 threadutil.initexitnotify()
138 t = ExitNotifyThread(target=syncmaster.syncitall,
139 name='Sync Runner',
140 kwargs = {'accounts': syncaccounts,
141 'config': config})
142 t.setDaemon(1)
143 t.start()
144 try:
145 threadutil.exitnotifymonitorloop(threadutil.threadexited)
146 except SystemExit:
147 raise
148 except:
149 ui.mainException() # Also expected to terminate.
150
151