]> code.delx.au - offlineimap/blobdiff - offlineimap/imapserver.py
Patch to make exit on Ctrl-C cleaner
[offlineimap] / offlineimap / imapserver.py
index 4e37ece334e6cfc8dad8a566e24d9b24034cce37..b0830c704d4b4ccd275713eefee5c9a736f3aef2 100644 (file)
@@ -20,9 +20,12 @@ import imaplib
 from offlineimap import imaplibutil, imaputil, threadutil
 from offlineimap.ui import UIBase
 from threading import *
-import thread, hmac, os
+import thread, hmac, os, time
 import base64
 
+from StringIO import StringIO
+from platform import system
+
 try:
     # do we have a recent pykerberos?
     have_gss = False
@@ -60,10 +63,42 @@ class UsefulIMAP4(UsefulIMAPMixIn, imaplib.IMAP4):
     def open(self, host = '', port = imaplib.IMAP4_PORT):
         imaplibutil.new_open(self, host, port)
 
+    # This is a hack around Darwin's implementation of realloc() (which
+    # Python uses inside the socket code). On Darwin, we split the
+    # message into 100k chunks, which should be small enough - smaller
+    # might start seriously hurting performance ...
+
+    def read(self, size):
+        if (system() == 'Darwin') and (size>0) :
+            read = 0
+            io = StringIO()
+            while read < size:
+                data = imaplib.IMAP4.read (self, min(size-read,8192))
+                read += len(data)
+                io.write(data)
+            return io.getvalue()
+        else:
+            return imaplib.IMAP4.read (self, size)
+
 class UsefulIMAP4_SSL(UsefulIMAPMixIn, imaplibutil.WrappedIMAP4_SSL):
     def open(self, host = '', port = imaplib.IMAP4_SSL_PORT):
         imaplibutil.new_open_ssl(self, host, port)
 
+    # This is the same hack as above, to be used in the case of an SSL
+    # connexion.
+
+    def read(self, size):
+        if (system() == 'Darwin') and (size>0) :
+            read = 0
+            io = StringIO()
+            while read < size:
+                data = imaplibutil.WrappedIMAP4_SSL.read (self, min(size-read,8192))
+                read += len(data)
+                io.write(data)
+            return io.getvalue()
+        else:
+            return imaplibutil.WrappedIMAP4_SSL.read (self,size)
+
 class UsefulIMAP4_Tunnel(UsefulIMAPMixIn, imaplibutil.IMAP4_Tunnel): pass
 
 class IMAPServer:
@@ -72,7 +107,7 @@ class IMAPServer:
     def __init__(self, config, reposname,
                  username = None, password = None, hostname = None,
                  port = None, ssl = 1, maxconnections = 1, tunnel = None,
-                 reference = '""'):
+                 reference = '""', sslclientcert = None, sslclientkey = None):
         self.reposname = reposname
         self.config = config
         self.username = username
@@ -83,6 +118,8 @@ class IMAPServer:
         self.tunnel = tunnel
         self.port = port
         self.usessl = ssl
+        self.sslclientcert = sslclientcert
+        self.sslclientkey = sslclientkey
         self.delim = None
         self.root = None
         if port == None:
@@ -218,7 +255,8 @@ class IMAPServer:
                 success = 1
             elif self.usessl:
                 UIBase.getglobalui().connecting(self.hostname, self.port)
-                imapobj = UsefulIMAP4_SSL(self.hostname, self.port)
+                imapobj = UsefulIMAP4_SSL(self.hostname, self.port,
+                                          self.sslclientkey, self.sslclientcert)
             else:
                 UIBase.getglobalui().connecting(self.hostname, self.port)
                 imapobj = UsefulIMAP4(self.hostname, self.port)
@@ -306,7 +344,7 @@ class IMAPServer:
         ui.debug('imap', 'keepalive thread started')
         while 1:
             ui.debug('imap', 'keepalive: top of loop')
-            event.wait(timeout)
+            time.sleep(timeout)
             ui.debug('imap', 'keepalive: after wait')
             if event.isSet():
                 ui.debug('imap', 'keepalive: event is set; exiting')
@@ -360,6 +398,8 @@ class ConfigedIMAPServer(IMAPServer):
             user = self.repos.getuser()
             port = self.repos.getport()
             ssl = self.repos.getssl()
+            sslclientcert = self.repos.getsslclientcert()
+            sslclientkey = self.repos.getsslclientkey()
         reference = self.repos.getreference()
         server = None
         password = None
@@ -379,4 +419,6 @@ class ConfigedIMAPServer(IMAPServer):
             IMAPServer.__init__(self, self.config, self.repos.getname(),
                                 user, password, host, port, ssl,
                                 self.repos.getmaxconnections(),
-                                reference = reference)
+                                reference = reference,
+                                sslclientcert = sslclientcert,
+                                sslclientkey = sslclientkey)