
Gh\c           @   sh  d  d l  Z  d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l m Z d  d l m	 Z	 d  d l
 m Z m Z d  d l m Z m Z m Z m Z m Z d  d l Z d  d l Z d  d l m Z m Z m Z m Z d  d l m Z y d  d l Z e Z Wn e k
 r7e  Z n Xd e! f d	     YZ" d
 e! f d     YZ# d S(   iN(   t   gaierror(   t   exc_info(   t   SSLErrort   cert_time_to_seconds(   t   Lockt   BoundedSemaphoret   Threadt   Eventt   currentThread(   t   imaplibutilt   imaputilt
   threadutilt   OfflineImapError(   t   getglobaluit
   IMAPServerc           B   s   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z e d  Z RS(   s"  Initializes all variables from an IMAPRepository() instance

    Various functions, such as acquireconnection() return an IMAP4
    object on which we can operate.

    Public instance variables are: self.:
     delim The server's folder delimiter. Only valid after acquireconnection()
    c         C   s{  t    |  _ | |  _ | j   |  _ | j   |  _ | j   |  _ |  j rt |  j rt t	 d | d t	 j
 j   n  |  j r |  j n |  j |  _ |  j r d	 n	 | j   |  _ | j   |  _ | j   |  _ d	 |  _ d	 |  _ d	 |  _ | j   |  _ | j   |  _ |  j t k r%t j |  _ n* |  j t k rCt j  |  _ n t j! |  _ |  j sa|  j rgd	 n	 | j"   |  _# | j$   |  _% |  j% d	 k r|  j rd n d |  _% n  | j&   |  _' | j(   |  _) | j*   |  _+ |  j+ d	 k rd	 |  _, n  | j-   |  _. | j/   |  _0 | j1   |  _2 | j3   |  _4 |  j ri|  j0 d k	 ri|  j2 d	 k rit5 d   n  | j6   |  _7 | j8   |  _9 | j:   |  _; | j<   |  _= | j>   |  _? d	 |  _@ d	 |  _A d	 |  _B | jC   |  _D g  |  _E g  |  _F i  |  _G tH |  jD  |  _I tJ   |  _K | jL   |  _M | jN   |  _O d	 |  _P t |  _Q |  jR d t j  |  _S |  jR d |  jS  |  _T d	 S(
   s"   :repos: a IMAPRepository instance.s   %s: sM   you must enable precisely one type of tunnel (preauth or transport), not bothi  i   t
   tls_compatsN   When 'tls_level' is not 'tls_compat' the 'ssl_version' must be set explicitly.t   proxyt	   authproxyN(U   R   t   uit   repost	   getconfigt   configt   getpreauthtunnelt   preauth_tunnelt   gettransporttunnelt   transport_tunnelR   t   ERRORt   REPOt   tunnelt   Nonet   getusert   usernamet   get_remote_identityt   user_identityt   get_auth_mechanismst	   authmechst   passwordt   passworderrort   goodpasswordt   getsslt   usesslt   getipv6t   useipv6t   Truet   sockett   AF_INET6t   aft   Falset   AF_INETt	   AF_UNSPECt   gethostt   hostnamet   getportt   portt   getsslclientcertt   sslclientcertt   getsslclientkeyt   sslclientkeyt   getsslcacertfilet   sslcacertfilet   _IMAPServer__verifycertt   get_ssl_fingerprintt   fingerprintt   gettlslevelt   tlslevelt   getsslversiont
   sslversiont   getstarttlst   starttlst	   Exceptiont   getoauth2_refresh_tokent   oauth2_refresh_tokent   getoauth2_access_tokent   oauth2_access_tokent   getoauth2_client_idt   oauth2_client_idt   getoauth2_client_secrett   oauth2_client_secrett   getoauth2_request_urlt   oauth2_request_urlt   oauth2_access_token_expires_att   delimt   roott   getmaxconnectionst   maxconnectionst   availableconnectionst   assignedconnectionst	   lastownerR   t	   semaphoreR   t   connectionlockt   getreferencet	   referencet   getidlefolderst   idlefolderst   gss_vct   gssapit
   _get_proxyt   proxied_sockett   authproxied_socket(   t   selfR   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __init__7   s|    	
			'										c   
      C   s  d |  j  j j } |  j j | |  s, | S|  j j | |  } | d k rT t j SyW d d  l } | j d  \ } } } t	 |  } | j
 t | |  | |  | j SWnb t k
 r |  j j d  nB t t f k
 r}	 |  j j d | |  j  j j |	 | f  n X| S(   Ns   Account t    it   :s-   PySocks not installed, ignoring proxy option.s:   Bad proxy option %s for account %s: %s Ignoring %s option.(   R   t   accountt   nameR   t
   has_optiont   getR,   t   sockst   splitt   intt   setdefaultproxyt   getattrt
   socksockett   ImportErrorR   t   warnt   AttributeErrort
   ValueError(
   Rc   t   proxysectiont
   dfltsockett   _account_sectionR   Rk   t
   proxy_typet   hostR5   t   e(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR`      s$    !c         C   s~   |  j  d k r |  j  S|  j d k r; |  j d k r; |  j S|  j j   ph |  j j |  j |  j	 |  j  |  _ d |  _ |  j S(   s#   Returns the server password or NoneN(
   R&   R   R$   R%   R   t   getpasswordR   t   getpassR   R   (   Rc   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __getpassword   s    $	c         C   sm   | j    } |  j j d d |  |  j   } |  j d t j | |  j   } |  j j d d |  | S(   Nt   imaps   __md5handler: got challenge %st    s   __md5handler: returning %s(   t   stripR   t   debugt   _IMAPServer__getpasswordR   t   hmact   newt	   hexdigest(   Rc   t   responset	   challenget   passwdt   retval(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __md5handler   s    #c         C   s0   |  j  j d d  | j |  j |  j    d S(   s(    Basic authentication via LOGIN command.R~   s$   Attempting IMAP LOGIN authenticationN(   R   R   t   loginR   R   (   Rc   t   imapobj(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __loginauth   s    c         C   s   |  j  } | s4 t d |  j j   t j j   n  |  j   } d } |  j d k ra |  j } n  d } | j	 | | | f  } | j	 | | d f  } |  j
 j d d |  | S(   s\   Implements SASL PLAIN authentication, RFC 4616,
          http://tools.ietf.org/html/rfc4616s   No username provided for '%s'Re   s    s   (passwd hidden for log)R~   s   __plainhandler: returning %sN(   R   R   R   t   getnameR   R   R   R!   R   t   joinR   R   (   Rc   R   t   authcR   t   authzt   NULLR   t   logsafe_retval(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __plainhandler   s    	c   
      C   s  t  j  j   } |  j rF |  j | k  rF d  |  _ |  j j d d  n  |  j d  k rF|  j d  k r t d |  t j	 j
   n  i  } |  j | d <|  j | d <|  j | d <d | d <|  j j d d |  j  |  j j d d	 |  t j } |  j t _ z y( t j |  j t j |   j   } Wn t k
 r} y d
 | t |  f } Wn# t k
 ry} d | | f } n Xt j t |  t |  |  t   d  n XWd  | t _ Xt j |  } |  j j d d |  d | k rt d | t j	 j
   n  | d |  _ d | k rF| t  j d | d d  |  _ qFn  |  j j d d |  j |  j f  d |  j |  j f }	 |  j j d d |	  |	 S(   NR~   s+   xoauth2handler: oauth2_access_token expireds;   No remote oauth2_request_url for repository '%s' specified.t	   client_idt   client_secrett   refresh_tokent
   grant_types   xoauth2handler: url "%s"s   xoauth2handler: params "%s"s   %s (configuration is: %s)s%   %s [cannot display configuration: %s]i   s   xoauth2handler: response "%s"u   errors   xoauth2handler got: %st   access_tokenu
   expires_int   secondst
   expires_ins,   xoauth2handler: access_token "%s expires %s"s   user=%sauth=Bearer %ss   xoauth2handler: returning "%s"(   t   datetimet   nowRP   R   RI   R   R   RO   R   R   R   RK   RM   RG   R,   Rb   t   urllibt   urlopent	   urlencodet   readRE   t   strt   sixt   reraiset   typeR   t   jsont   loadst	   timedeltaR   (
   Rc   R   R   t   paramst   original_socketRz   t   msgt   eparamst   respt   auth_string(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __xoauth2handler   sZ    		
	 "4

c         C   sb  | d k r d  } n  y|  j s^ t j d |  j t j j  } t j d d d |  |  _ n  |  j j s |  j j	 |  } | r | Sd S| d  k r d S|  j j
 |  } g  } | j d d !| d d +d | d <|  j r |  j | d	 )n  d j |  } |  j j | | j  } | j r#| j Sd SWn3 t j j k
 r]} |  j j d
 | j    d  SXd  S(   NRe   s   imap@t   usaget   initiateRh   i    i   s   i   R~   (   R   R^   R_   t   NameR3   t   NameTypet   hostbased_servicet   SecurityContextt   completet   stept   unwrapt   messageR   R   t   wrapt	   encryptedt
   exceptionst   GSSErrorR   R   t   gen_message(   Rc   t   tokenRh   R   t   replyt   err(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __gsshandler  s2    		
	c         C   s   d | j  k r |  j r |  j j d d  y | j   Wq | j k
 r~ } t d t |  t j j	 d  t   d   q Xn  d  S(   Nt   STARTTLSR~   s   Using STARTTLS connections"   Failed to start TLS connection: %si   (   t   capabilitiesR(   R   R   RD   t   errorR   R   R   R   R   R   (   Rc   R   Rz   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __start_tlsG  s    
c         C   s   t  s
 t S|  j j   zV y | j d |  j  t SWn" | j k
 rY } t |  _   n Xt |  _ d  |  _
 Wd  |  j j   Xd  S(   Nt   GSSAPI(   t   have_gssR/   RY   t   acquiret   authenticatet   _IMAPServer__gsshandlerR+   R   R_   R   R^   t   release(   Rc   R   Rz   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_gssapib  s     		c         C   s   | j  d |  j  t S(   Ns   CRAM-MD5(   R   t   _IMAPServer__md5handlerR+   (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_cram_md5s  s    c         C   s   | j  d |  j  t S(   Nt   PLAIN(   R   t   _IMAPServer__plainhandlerR+   (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_plainw  s    c         C   s9   |  j  d  k r" |  j d  k r" t S| j d |  j  t S(   Nt   XOAUTH2(   RG   R   RI   R/   R   t   _IMAPServer__xoauth2handlerR+   (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_xoauth2{  s
    c         C   s<   d | j  k r' t d t j j   n |  j |  t Sd  S(   Nt   LOGINDISABLEDs3   IMAP LOGIN is disabled by server.  Need to use SSL?(   R   R   R   R   t   _IMAPServer__loginauthR+   (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_login  s
    c         C   s  g  } t  } t  } i |  j t  t f d 6|  j t t f d 6|  j t t f d 6|  j t t f d 6|  j t t  f d 6} x|  j D]	} | | k r t d |   n  | | \ } } }	 | r |  j	 r | r t } |  j
 |  n  |	 rd | }
 |
 | j k rq qn  t } |  j j d d	 |  y | |  r=d
 SWq | j t f k
 r} |  j j d | | f  | j | | f  q Xq Wt |  rd j g  | D]) } d j | d t | d  f  ^ q } t d | t j j   n  | s~d j g  g  | j D] } | d d !d k r| ^ qD] } | d ^ q1 } t d |  j d j |  j  | f t j j   n  d
 S(   sg  Authentication machinery for self.acquireconnection().

        Raises OfflineImapError() of type ERROR.REPO when
        there are either fatal problems or no authentications
        succeeded.

        If any authentication method succeeds, routine should exit:
        warnings for failed methods are to be produced in the
        respective except blocks.R   R   s   CRAM-MD5R   t   LOGINs:   Bad authentication method %s, please, file OfflineIMAP bugs   AUTH=R~   u   Attempting %s authenticationNs   %s authentication failed: %ss   
	s   : i    i   s$   All authentication types failed:
	%ss   , i   u`   Repository %s: no supported authentication mechanisms found; configured %s, server advertises %s(   R/   t   _IMAPServer__authn_gssapiR+   t   _IMAPServer__authn_xoauth2t   _IMAPServer__authn_cram_md5t   _IMAPServer__authn_plaint   _IMAPServer__authn_loginR#   RE   RD   t   _IMAPServer__start_tlsR   R   R   R   R   Rr   t   appendt   lenR   R   R   R   R   (   Rc   R   t	   exc_stackt   tried_to_authnt	   tried_tlst   auth_methodst   mt   funct   tryTLSt	   check_capt   capRz   t   xR   t   methods(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __authn_helper  sR    
	?	Fc         C   sg  d } | s d | S| j    } g  } | j d  } | rd t j   t |  k rd d | | f Sn  xL | j d g   D]8 } | d \ } }	 | d k rw | j |	 j     qw qw Wt |  d k r d | SxB | j d	 g   D]. \ } }	 | d
 k r | j |	 j     q q WxJ | D]B }
 |
 | k sWd | k r|
 d | j d d  d k rd SqWd | S(   s   Verify that cert (in socket.getpeercert() format) matches hostname.

        CRLs are not handled.
        Returns error message if any problems are found and None on success.s   CA Cert verifying failed: s   %s no certificate receivedt   notAfters   %s certificate expired %st   subjecti    t
   commonNames%   %s no commonName found in certificatet   subjectAltNamet   DNSt   .s   *.i   s/   %s no matching domain name found in certificateN(   t   lowerRj   t   timeR   R   R   Rl   R   (   Rc   t   certR3   t   errstrt   dnsnamet	   certnamest   notaftert   st   keyt   valuet   certname(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __verifycert  s.    ,c         C   se  |  j  j   |  j j   t   } d } t |  j  r x^ t t |  j  d d d  D]= } |  j | } |  j | | j	 k rX | } |  j | =PqX qX W| s |  j d } |  j d =n  |  j
 j |  | j	 |  j | <|  j j   | S|  j j   t } yx| t k	 r|  j rj|  j j |  j j   d |  j  t j |  j d t j   d |  j } t } n6|  j rE|  j j |  j j   |  j |  j  |  j j d d |  j j   |  j |  j f  t j d	 |  j d
 |  j d |  j  d |  j! d |  j" d |  j# d |  j d t j   d |  j$ d |  j d |  j d |  j%  } n[ |  j j |  j j   |  j |  j  t j& |  j |  j d t j   d |  j d |  j% } |  j' sy# |  j( |  |  j) |  _* t } Wqt+ k
 r} t, |  |  _-   qXqqW|  j j. d d  r| j/   n  | j0   \ } } | d g k r`t1 | d j2   j3    | _4 n  |  j5 d k re| j6 |  j7 d  d }	 |	 d g k s|	 d k r| j6 |  j7 d  d }	 n  |	 d g k s|	 d k rd |  j j   |  j7 f }
 |  j j8 |
  t9 |
   n  t: j; |	 d  d \ |  _5 |  _< t: j= |  j5  |  _5 t: j= |  j<  |  _< n  |  j % |  j
 j |  | j	 |  j | <Wd QX| SWnt9 k
 r`} |  j  j   t+ j> j? } t@ |  tA k rd |  j |  j f } tB jC t+ t+ | |  tD   d  n tE | tF  r| jG tG jH k r|  j d k r_d |  j |  j | f } n d |  j |  j | f } tB jC t+ t+ | |  tD   d  nj tE | t jI  r| jJ d tG jK k rd |  j |  j |  j f } tB jC t+ t+ | |  tD   d  n  t, |  d  d k rZtB jC t+ t+ d  |  j |  j f t+ j> j?  tD   d  qa  n Xd S(!   s   Fetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object.i   ii    R   t   timeoutt
   use_socketR~   s   %s: level '%s', version '%s'Ry   R5   t   keyfilet   certfilet   ca_certst   cert_verify_cbt   ssl_versionR>   t	   tls_levelR.   t   usecompressions   ""s   "*"s'   Server '%s' returned no folders in '%s'Ns   Could not resolve name '%s' for repository '%s'. Make sure you have configured the server name correctly and that you are online.i   i  s   Could not connect via SSL to host '%s' and non-standard ssl port %d configured. Make sure you connect to the correct port. Got: %ssW   Unknown SSL protocol connecting to host '%s' for repository '%s'. OpenSSL responded:
%ss   Connection to host '%s:%d' for repository '%s' was refused. Make sure you have the right host and port configured and that you are actually able to access the network.i   s   can't open socket; errorsT   Could not connect to remote server '%s' for repository '%s'. Remote does not answer.(L   RX   R   RY   R   R   R   RU   t   rangeRW   t   identRV   R   R   R/   R+   R   R   t
   connectingR   R   R	   t   IMAP4_TunnelR,   t   getdefaulttimeoutRa   R(   R3   R5   R   R@   RB   t   WrappedIMAP4_SSLR9   R7   R;   R<   R>   R.   t   WrappedIMAP4R   t   _IMAPServer__authn_helperR$   R&   R   R   R%   t   getconfbooleant   enable_compressiont
   capabilityt   tuplet   upperRl   R   RQ   t   listR[   Rr   RE   R
   t	   imapsplitRR   t   dequoteR   R   R   R    R   R   R   t
   isinstanceR   t   errnot   EPERMR   t   argst   ECONNREFUSED(   Rc   t	   curThreadR   t   it   tryobjt   successRz   t   typt   datt   listresR   t   severityt   reason(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   acquireconnection  s    	&
						 														
"#
	!	(		c         C   s   |  j  j   |  j  j   d S(   s  Waits until there is a connection available.

        Note that between the time that a connection becomes available and the
        time it is requested, another thread may have grabbed it.  This function
        is mainly present as a way to avoid spawning thousands of threads to
        copy messages, then have them all wait for 3 available connections.
        It's OK if we have maxconnections + 1 or 2 threads, which is what this
        will help us do.N(   RX   R   R   (   Rc   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   connectionwait  s    
c         C   s|   |  j  m t j |  j |  j  x" |  j |  j D] } | j   q1 Wg  |  _ g  |  _ i  |  _ d  |  _
 t |  _ Wd  QXd  S(   N(   RY   R   t   semaphoreresetRX   RT   RV   RU   t   logoutRW   R   R^   R/   R_   (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   close  s    
				c         C   si  |  j  j d d  x<| j   sQ|  j j   t |  j  t |  j  } |  j j   g  } x t	 |  D]t } |  j  j d d | | f  t |  j
  | k r t |  |  j
 |  } n t |   } | j   | j |  qk W|  j  j d d  | j |  |  j  j d d  x" | D] } | j   | j   qW|  j  j d d  q W|  j  j d d  d S(	   s;  Sends a NOOP to each connection recorded.

        It will wait a maximum of timeout seconds between doing this, and will
        continue to do so until the Event object as passed is true.  This method
        is expected to be invoked in a separate thread, which should be join()'d
        after the event is set.R~   s   keepalive thread starteds)   keepalive: processing connection %d of %ds   keepalive: waiting for timeouts   keepalive: after waits   keepalive: all threads joineds    keepalive: event is set; exitingN(   R   R   t   isSetRY   R   R   RV   RU   R   R	  R]   t
   IdleThreadt   startR   t   waitt   stopR   (   Rc   R   t   eventt   numconnectionst   threadsR  t   idler(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt	   keepalive  s0    

c         C   sw   | d k r d S|  j j   |  j j |  | j s< | rI | j   n |  j j |  |  j j	   |  j
 j	   d S(   s   Releases a connection, returning it to the pool.

        :param drop_conn: If True, the connection will be released and
           not be reused. This can be used to indicate broken connections.N(   R   RY   R   RV   t   removet	   TerminateR*  RU   R   R   RX   (   Rc   t
   connectiont	   drop_conn(    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   releaseconnection  s    (   t   __name__t
   __module__t   __doc__Rd   R`   R   R   R   R   R   R   R   R   R   R   R   R   R  R<   R'  R(  R+  R5  R/   R:  (    (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR   -   s,   	\							;	-							H	'				)R-  c           B   sJ   e  Z d d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 RS(   c         C   sw   | |  _  | |  _ t   |  _ t   |  _ | d k rN t d |  j  |  _	 n t d |  j
  |  _	 |  j	 j d  d S(   s   If invoked without 'folder', perform a NOOP and wait for
        self.stop() to be called. If invoked with folder, switch to IDLE
        mode and synchronize once we have a new messaget   targeti   N(   t   parentt   folderR   t   stop_sigR   R   R   R   t   noopt   threadt   _IdleThread__idlet	   setDaemon(   Rc   R?  R@  (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyRd   	  s    		c         C   s   |  j  j   d  S(   N(   RC  R.  (   Rc   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR.    s    c         C   s   |  j  j   d  S(   N(   RA  t   set(   Rc   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR0    s    c         C   s   |  j  j   d  S(   N(   RC  R   (   Rc   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR     s    c         C   s   |  j  j   } zY y | j   WnD | j k
 rf |  j j d | j  |  j  j | t  d  } n XWd  | r |  j  j |  |  j
 j   n  Xd  S(   Ns(   Attempting NOOP on dropped connection %s(   R?  R'  RB  t   abortR   Rr   t
   identifierR:  R+   R   RA  R/  (   Rc   R   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyRB  !  s     c         C   s   |  j  j } | j } | j } | j } | j } | j |  j d t } | j	 d d  } | j
 |  t j j | | d t | j	 d d  } | j
 |  t   } | j t    d  S(   Nt   decodet   presynchookRe   t   quickt   postsynchook(   R?  R   Rg   t
   localrepost   remoterepost   statusrepost	   getfolderR@  R/   t   getconft   callhookt   offlineimapt   accountst
   syncfolderR   t   unregisterthreadR   (   Rc   RN  Rg   RM  RO  t   remotefoldert   hookR   (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __dosync5  s    					c            s    f d   }   f d   } xe  j  j   st   _ t } x | s  j j   } y | j   j  Wn t k
 r } | j	 t j
 j k r   j j | t   d    j j | t  q| j	 t j
 j k r   j j | t   d  q  qB Xt } qB Wd | j k r'| j d |  n!   j j d | j  | |    j  j   | |    j r!   j  j     j   q! q! Wd S(   s9   Invoke IDLE mode until timeout or self.stop() is invoked.c            sH   |  \ } } } | d k r7   j j   r7 t   _ n    j j   d S(   s   IDLE callback function invoked by imaplib2.

            This is invoked when a) The IMAP server tells us something
            while in IDLE mode, b) we get an Exception (e.g. on dropped
            connections, or c) the standard imaplib IDLE timeout of 29
            minutes kicks in.N(   R   RA  R,  R+   t   needsyncRF  (   R  t   resultt   cb_argt   exc_data(   Rc   (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   callbackI  s    c            sc   y |  j    Wn> |  j k
 rN   j j d |  j    j j |  t  n X  j j |   d S(   s   Factorize the noop code.s(   Attempting NOOP on dropped connection %sN(   RB  RG  R   Rr   RH  R?  R:  R+   (   R   (   Rc   (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyRB  W  s    i   t   IDLER^  sF   IMAP IDLE not supported on server '%s'.Sleep until next refresh cycle.N(   RA  R,  R/   RZ  R?  R'  t   selectR@  R   R%  R   t   FOLDER_RETRYR   R   R   R:  R+   t   FOLDERR   t   idleRr   RH  R/  t   cleart   _IdleThread__dosync(   Rc   R^  RB  R!  R   Rz   (    (   Rc   s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   __idleF  s6    		


	N(
   R;  R<  R   Rd   R.  R0  R   RB  Re  RD  (    (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyR-    s   					($   R   R   R,   R   R   R   R  R    t   sysR   t   sslR   R   t	   threadingR   R   R   R   R   R   t   offlineimap.accountsRS  R	   R
   R   R   t   offlineimap.uiR   R_   R+   R   Rq   R/   t   objectR   R-  (    (    (    s0   /usr/share/offlineimap/offlineimap/imapserver.pyt   <module>   s0   ("

  